--- a/CMakeLists.txt Mon Jul 01 22:28:42 2013 +0300
+++ b/CMakeLists.txt Mon Jul 01 23:23:22 2013 +0300
@@ -30,11 +30,8 @@
option(BUILD_ENGINE_LIBRARY "Enable hwengine library (off)" OFF)
option(ANDROID "Enable Android build (off)" OFF)
-if(UNIX AND NOT APPLE)
- option(MINIMAL_FLAGS "Respect system flags as much as possible (off)" OFF)
-else()
- option(NOAUTOUPDATE "Disable OS X Sparkle update checking" OFF)
-endif()
+option(MINIMAL_FLAGS "Respect system flags as much as possible (off)" OFF)
+option(NOAUTOUPDATE "Disable OS X Sparkle update checking (off)" OFF)
set(FPFLAGS "" CACHE STRING "Additional Freepascal flags")
set(GHFLAGS "" CACHE STRING "Additional Haskell flags")
@@ -75,43 +72,39 @@
#perform safe check that enable/disable compilation features
include(${CMAKE_MODULE_PATH}/compilerchecks.cmake)
-#set default flags values for all projects (unless MINIMAL_FLAGS is true)
-if(NOT ${MINIMAL_FLAGS})
- set(CMAKE_C_FLAGS "-pipe ${CMAKE_C_FLAGS}")
- set(CMAKE_C_FLAGS_RELEASE "-w -Os -fomit-frame-pointer ${CMAKE_C_FLAGS_RELEASE}")
- set(CMAKE_C_FLAGS_DEBUG "-Wall -O0 -g ${CMAKE_C_FLAGS_DEBUG}")
- set(CMAKE_CXX_FLAGS "-pipe ${CMAKE_CXX_FLAGS}")
- set(CMAKE_CXX_FLAGS_RELEASE "-w -Os -fomit-frame-pointer ${CMAKE_CXX_FLAGS_RELEASE}")
- set(CMAKE_CXX_FLAGS_DEBUG "-Wall -O0 -g ${CMAKE_CXX_FLAGS_DEBUG}")
-else()
- #CMake adds a lot of additional configuration flags, so let's clear them up
- set(CMAKE_C_FLAGS_RELEASE "")
- set(CMAKE_C_FLAGS_DEBUG "-Wall")
- set(CMAKE_CXX_FLAGS_RELEASE "")
- set(CMAKE_CXX_FLAGS_DEBUG "-Wall")
+#set default compiler flags
+add_flag_append(CMAKE_C_FLAGS "-Wall -pipe")
+add_flag_append(CMAKE_C_FLAGS_RELEASE "-Os")
+add_flag_append(CMAKE_C_FLAGS_DEBUG "-Wextra -O0")
+add_flag_append(CMAKE_CXX_FLAGS "-Wall -pipe")
+add_flag_append(CMAKE_CXX_FLAGS_RELEASE "-Os")
+add_flag_append(CMAKE_CXX_FLAGS_DEBUG "-Wextra -O0")
+add_flag_append(CMAKE_Pascal_FLAGS "-Cs2000000")
+add_flag_append(CMAKE_Pascal_FLAGS_DEBUG "-O- -gv")
+add_flag_append(CMAKE_Pascal_FLAGS_RELEASE "-Os -Xs")
+
+#CMake adds a lot of additional configuration flags, so let's clear them up
+if(${MINIMAL_FLAGS})
+ unset(CMAKE_C_FLAGS_RELEASE)
+ unset(CMAKE_C_FLAGS_DEBUG)
+ unset(CMAKE_CXX_FLAGS_RELEASE)
+ unset(CMAKE_CXX_FLAGS_DEBUG)
endif()
+
#parse additional parameters
if(FPFLAGS)
add_flag_prepend(CMAKE_Pascal_FLAGS ${FPFLAGS})
endif()
if(GHFLAGS)
- if(${allow_parse_args})
+ if(${CMAKE_VERSION} VERSION_GREATER 2.6)
separate_arguments(ghflags_parsed UNIX_COMMAND ${GHFLAGS})
else()
message(${WARNING} "FPFLAGS and GHFLAGS are available only when using CMake >= 2.8")
endif()
endif()
-
-list(APPEND haskell_flags ${ghflags_parsed} # user flags
- "-O2" # optimise for faster code
- )
-
-#-vm4079,4080,4081
-add_flag_append(CMAKE_Pascal_FLAGS "-Cs2000000")
-add_flag_append(CMAKE_Pascal_FLAGS_DEBUG "-O- -gv")
-add_flag_append(CMAKE_Pascal_FLAGS_RELEASE "-Os -Xs")
+list(APPEND haskell_flags ${ghflags_parsed} "-O2")
#get BUILD_TYPE and enable/disable optimisation
message(STATUS "Using ${CMAKE_BUILD_TYPE} configuration")
--- a/QTfrontend/campaign.cpp Mon Jul 01 22:28:42 2013 +0300
+++ b/QTfrontend/campaign.cpp Mon Jul 01 23:23:22 2013 +0300
@@ -28,8 +28,8 @@
QList<MissionInfo> missionInfoList;
QSettings teamfile(cfgdir->absolutePath() + "/Teams/" + teamName + ".hwt", QSettings::IniFormat, 0);
teamfile.setIniCodec("UTF-8");
- unsigned int progress = teamfile.value("Campaign " + campaignName + "/Progress", 0).toInt();
- unsigned int unlockedMissions = teamfile.value("Campaign " + campaignName + "/UnlockedMissions", 0).toInt();
+ int progress = teamfile.value("Campaign " + campaignName + "/Progress", 0).toInt();
+ int unlockedMissions = teamfile.value("Campaign " + campaignName + "/UnlockedMissions", 0).toInt();
QSettings campfile("physfs://Missions/Campaign/" + campaignName + "/campaign.ini", QSettings::IniFormat, 0);
campfile.setIniCodec("UTF-8");
@@ -59,8 +59,9 @@
{
MissionInfo missionInfo;
missionInfo.name = campfile.value(QString("Mission %1/Name").arg(i)).toString();
- missionInfo.script = campfile.value(QString("Mission %1/Script").arg(i)).toString();
- missionInfo.description = m_info.value(campaignName+"-"+ missionInfo.script.replace(QString(".lua"),QString("")) + ".desc",
+ QString script = campfile.value(QString("Mission %1/Script").arg(i)).toString();
+ missionInfo.script = script;
+ missionInfo.description = m_info.value(campaignName+"-"+ script.replace(QString(".lua"),QString("")) + ".desc",
QObject::tr("No description available")).toString();
QString image = campfile.value(QString("Mission %1/Script").arg(i)).toString().replace(QString(".lua"),QString(".png"));
missionInfo.image = ":/res/campaign/"+campaignName+"/"+image;
@@ -71,14 +72,15 @@
}
else if(unlockedMissions>0)
{
- for(unsigned int i=1;i<=unlockedMissions;i++)
+ for(int i=1;i<=unlockedMissions;i++)
{
QString missionNum = QString("%1").arg(i);
int missionNumber = teamfile.value("Campaign " + campaignName + "/Mission"+missionNum, -1).toInt();
MissionInfo missionInfo;
missionInfo.name = campfile.value(QString("Mission %1/Name").arg(missionNumber)).toString();
- missionInfo.script = campfile.value(QString("Mission %1/Script").arg(missionNumber)).toString();
- missionInfo.description = m_info.value(campaignName+"-"+ missionInfo.script.replace(QString(".lua"),QString("")) + ".desc",
+ QString script = campfile.value(QString("Mission %1/Script").arg(missionNumber)).toString();
+ missionInfo.script = script;
+ missionInfo.description = m_info.value(campaignName+"-"+ script.replace(QString(".lua"),QString("")) + ".desc",
QObject::tr("No description available")).toString();
QString image = campfile.value(QString("Mission %1/Script").arg(missionNumber)).toString().replace(QString(".lua"),QString(".png"));
missionInfo.image = ":/res/campaign/"+campaignName+"/"+image;
--- a/QTfrontend/hedgewars.qrc Mon Jul 01 22:28:42 2013 +0300
+++ b/QTfrontend/hedgewars.qrc Mon Jul 01 23:23:22 2013 +0300
@@ -28,17 +28,17 @@
<file>res/botlevels/net3.png</file>
<file>res/botlevels/net4.png</file>
<file>res/botlevels/net5.png</file>
- <file>res/campaign/A Classic Fairytale/first_blood.png</file>
- <file>res/campaign/A Classic Fairytale/shadow.png</file>
- <file>res/campaign/A Classic Fairytale/journey.png</file>
- <file>res/campaign/A Classic Fairytale/united.png</file>
- <file>res/campaign/A Classic Fairytale/backstab.png</file>
- <file>res/campaign/A Classic Fairytale/dragon.png</file>
- <file>res/campaign/A Classic Fairytale/family.png</file>
- <file>res/campaign/A Classic Fairytale/queen.png</file>
- <file>res/campaign/A Classic Fairytale/enemy.png</file>
- <file>res/campaign/A Classic Fairytale/epil.png</file>
- <file>res/campaign/A Space Adventure/cosmos.png</file>
+ <file>res/campaign/A_Classic_Fairytale/first_blood.png</file>
+ <file>res/campaign/A_Classic_Fairytale/shadow.png</file>
+ <file>res/campaign/A_Classic_Fairytale/journey.png</file>
+ <file>res/campaign/A_Classic_Fairytale/united.png</file>
+ <file>res/campaign/A_Classic_Fairytale/backstab.png</file>
+ <file>res/campaign/A_Classic_Fairytale/dragon.png</file>
+ <file>res/campaign/A_Classic_Fairytale/family.png</file>
+ <file>res/campaign/A_Classic_Fairytale/queen.png</file>
+ <file>res/campaign/A_Classic_Fairytale/enemy.png</file>
+ <file>res/campaign/A_Classic_Fairytale/epil.png</file>
+ <file>res/campaign/A_Space_Adventure/cosmos.png</file>
<file>res/bonus.png</file>
<file>res/Hedgehog.png</file>
<file>res/net.png</file>
--- a/QTfrontend/hwform.cpp Mon Jul 01 22:28:42 2013 +0300
+++ b/QTfrontend/hwform.cpp Mon Jul 01 23:23:22 2013 +0300
@@ -1722,10 +1722,9 @@
void HWForm::StartCampaign()
{
CreateGame(0, 0, 0);
- QString camp = ui.pageCampaign->CBCampaign->currentText();
+ QString camp = ui.pageCampaign->CBCampaign->currentText().replace(QString(" "),QString("_"));
QString miss = campaignMissionInfo[ui.pageCampaign->CBMission->currentIndex()].script;
QString campTeam = ui.pageCampaign->CBTeam->currentText();
-
game->StartCampaign(camp, miss, campTeam);
}
@@ -1886,7 +1885,7 @@
unsigned int n = entries.count();
for(unsigned int i = 0; i < n; i++)
{
- ui.pageCampaign->CBCampaign->addItem(QString(entries[i]), QString(entries[i]));
+ ui.pageCampaign->CBCampaign->addItem(QString(entries[i]).replace(QString("_"),QString(" ")), QString(entries[i]).replace(QString("_"),QString(" ")));
}
}
@@ -1894,7 +1893,7 @@
{
Q_UNUSED(index);
HWTeam team(ui.pageCampaign->CBTeam->currentText());
- QString campaignName = ui.pageCampaign->CBCampaign->currentText();
+ QString campaignName = ui.pageCampaign->CBCampaign->currentText().replace(QString(" "),QString("_"));
QString tName = team.name();
campaignMissionInfo = getCampMissionList(campaignName,tName);
@@ -1911,7 +1910,7 @@
void HWForm::UpdateCampaignPageMission(int index)
{
// update thumbnail and description
- QString campaignName = ui.pageCampaign->CBCampaign->currentText();
+ QString campaignName = ui.pageCampaign->CBCampaign->currentText().replace(QString(" "),QString("_"));
// when campaign changes the UpdateCampaignPageMission is triggered with wrong values
// this will cause segfault. This check prevents illegal memory reads
if(index > -1 && index < campaignMissionInfo.count()) {
Binary file QTfrontend/res/campaign/A Classic Fairytale/backstab.png has changed
Binary file QTfrontend/res/campaign/A Classic Fairytale/dragon.png has changed
Binary file QTfrontend/res/campaign/A Classic Fairytale/enemy.png has changed
Binary file QTfrontend/res/campaign/A Classic Fairytale/epil.png has changed
Binary file QTfrontend/res/campaign/A Classic Fairytale/family.png has changed
Binary file QTfrontend/res/campaign/A Classic Fairytale/first_blood.png has changed
Binary file QTfrontend/res/campaign/A Classic Fairytale/journey.png has changed
Binary file QTfrontend/res/campaign/A Classic Fairytale/queen.png has changed
Binary file QTfrontend/res/campaign/A Classic Fairytale/shadow.png has changed
Binary file QTfrontend/res/campaign/A Classic Fairytale/united.png has changed
Binary file QTfrontend/res/campaign/A Space Adventure/cosmos.png has changed
Binary file QTfrontend/res/campaign/A_Classic_Fairytale/backstab.png has changed
Binary file QTfrontend/res/campaign/A_Classic_Fairytale/dragon.png has changed
Binary file QTfrontend/res/campaign/A_Classic_Fairytale/enemy.png has changed
Binary file QTfrontend/res/campaign/A_Classic_Fairytale/epil.png has changed
Binary file QTfrontend/res/campaign/A_Classic_Fairytale/family.png has changed
Binary file QTfrontend/res/campaign/A_Classic_Fairytale/first_blood.png has changed
Binary file QTfrontend/res/campaign/A_Classic_Fairytale/journey.png has changed
Binary file QTfrontend/res/campaign/A_Classic_Fairytale/queen.png has changed
Binary file QTfrontend/res/campaign/A_Classic_Fairytale/shadow.png has changed
Binary file QTfrontend/res/campaign/A_Classic_Fairytale/united.png has changed
Binary file QTfrontend/res/campaign/A_Space_Adventure/cosmos.png has changed
--- a/QTfrontend/ui/page/pagecampaign.cpp Mon Jul 01 22:28:42 2013 +0300
+++ b/QTfrontend/ui/page/pagecampaign.cpp Mon Jul 01 23:23:22 2013 +0300
@@ -42,7 +42,7 @@
infoLayout->setRowStretch(1, 1);
// set this as default image first time page is created, this will change in hwform.cpp
- btnPreview = formattedButton(":/res/campaign/A Classic Fairytale/first_blood.png", true);
+ btnPreview = formattedButton(":/res/campaign/A_Classic_Fairytale/first_blood.png", true);
infoLayout->setAlignment(btnPreview, Qt::AlignHCenter | Qt::AlignVCenter);
lbldescription = new QLabel();
--- a/cmake_modules/compilerchecks.cmake Mon Jul 01 22:28:42 2013 +0300
+++ b/cmake_modules/compilerchecks.cmake Mon Jul 01 23:23:22 2013 +0300
@@ -11,9 +11,10 @@
#stack protection, when found it needs to go in the linker flags too
#it is disabled on win32 because it adds a dll and messes with linker
+#some bsd installations reported problems too
#(see 822312 654424 on bugzilla.redhat.com)
check_c_compiler_flag("-fstack-protector-all -fstack-protector" HAVE_STACKPROTECTOR)
-if(HAVE_STACKPROTECTOR AND (NOT WIN32))
+if(HAVE_STACKPROTECTOR AND ((NOT WIN32) OR (CMAKE_SYSTEM_NAME MATCHES BSD.OS)))
add_flag_append(CMAKE_C_FLAGS "-fstack-protector-all -fstack-protector")
add_flag_append(CMAKE_CXX_FLAGS "-fstack-protector-all -fstack-protector")
add_flag_append(CMAKE_EXE_LINKER_FLAGS "-fstack-protector-all -fstack-protector")
--- a/cmake_modules/platform.cmake Mon Jul 01 22:28:42 2013 +0300
+++ b/cmake_modules/platform.cmake Mon Jul 01 23:23:22 2013 +0300
@@ -2,10 +2,10 @@
if(APPLE)
set(CMAKE_FIND_FRAMEWORK "FIRST")
-#what system are we building for
+ #what system are we building for
set(minimum_macosx_version $ENV{MACOSX_DEPLOYMENT_TARGET})
-#detect on which system we are: if sw_vers cannot be found for any reason (re)use minimum_macosx_version
+ #detect on which system we are: if sw_vers cannot be found for any reason (re)use minimum_macosx_version
find_program(sw_vers sw_vers)
if(sw_vers)
execute_process(COMMAND ${sw_vers} "-productVersion"
@@ -21,41 +21,62 @@
endif()
endif()
-#if nothing is set, we deploy only for the current system
+ #if nothing is set, we deploy only for the current system
if(NOT minimum_macosx_version)
set(minimum_macosx_version ${current_macosx_version})
endif()
-#lower systems don't have enough processing power anyway
+ #lower systems don't have enough processing power anyway
if (minimum_macosx_version VERSION_LESS "10.4")
message(FATAL_ERROR "Hedgewars is not supported on Mac OS X pre-10.4")
endif()
-#workaround for http://playcontrol.net/ewing/jibberjabber/big_behind-the-scenes_chang.html#SDL_mixer (Update 2)
+ #workaround for http://playcontrol.net/ewing/jibberjabber/big_behind-the-scenes_chang.html#SDL_mixer (Update 2)
if(current_macosx_version VERSION_EQUAL "10.4")
find_package(SDL_mixer REQUIRED)
set(DYLIB_SMPEG "-dylib_file @loader_path/Frameworks/smpeg.framework/Versions/A/smpeg:${SDLMIXER_LIBRARY}/Versions/A/Frameworks/smpeg.framework/Versions/A/smpeg")
set(DYLIB_MIKMOD "-dylib_file @loader_path/Frameworks/mikmod.framework/Versions/A/mikmod:${SDLMIXER_LIBRARY}/Versions/A/Frameworks/mikmod.framework/Versions/A/mikmod")
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${DYLIB_SMPEG} ${DYLIB_MIKMOD}")
- set(CMAKE_CX_FLAGS "${CMAKE_CX_FLAGS} ${DYLIB_SMPEG} ${DYLIB_MIKMOD}")
- list(APPEND pascal_flags "-k${DYLIB_SMPEG}" "-k${DYLIB_MIKMOD}")
+ add_flag_append(CMAKE_C_FLAGS "${DYLIB_SMPEG} ${DYLIB_MIKMOD}")
+ add_flag_append(CMAKE_CXX_FLAGS "${DYLIB_SMPEG} ${DYLIB_MIKMOD}")
+ add_flag_append(CMAKE_Pascal_FLAGS "-k${DYLIB_SMPEG} -k${DYLIB_MIKMOD}")
endif()
-#CMAKE_OSX_ARCHITECTURES and CMAKE_OSX_SYSROOT need to be set for universal binary and correct linking
if(NOT CMAKE_OSX_ARCHITECTURES)
if(current_macosx_version VERSION_LESS "10.6")
+ #SDL is only 32 bit on lower OS
if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "powerpc*")
set(CMAKE_OSX_ARCHITECTURES "ppc7400")
else()
set(CMAKE_OSX_ARCHITECTURES "i386")
endif()
- else()
- set(CMAKE_OSX_ARCHITECTURES "x86_64")
endif()
endif()
-#CMAKE_OSX_SYSROOT is set at the system version we are supposed to build on
-#we need to provide the correct one when host and target differ
+ #parse this system variable and adjust only the powerpc syntax to be compatible with -P
+ if(CMAKE_OSX_ARCHITECTURES)
+ string(REGEX MATCH "[pP][pP][cC]+" powerpc_build "${CMAKE_OSX_ARCHITECTURES}")
+ string(REGEX MATCH "[iI]386+" i386_build "${CMAKE_OSX_ARCHITECTURES}")
+ string(REGEX MATCH "[xX]86_64+" x86_64_build "${CMAKE_OSX_ARCHITECTURES}")
+ if(x86_64_build)
+ add_flag_prepend(CMAKE_Pascal_FLAGS -Px86_64)
+ elseif(i386_build)
+ add_flag_prepend(CMAKE_Pascal_FLAGS -Pi386)
+ elseif(powerpc_build)
+ add_flag_prepend(CMAKE_Pascal_FLAGS -Ppowerpc)
+ else()
+ message(FATAL_ERROR "Unknown architecture present in CMAKE_OSX_ARCHITECTURES (${CMAKE_OSX_ARCHITECTURES})")
+ endif()
+ list(LENGTH CMAKE_OSX_ARCHITECTURES num_of_archs)
+ if(num_of_archs GREATER 1)
+ message(${WARNING} "Only one architecture in CMAKE_OSX_ARCHITECTURES is currently supported, picking the first one")
+ endif()
+ elseif(CMAKE_SIZEOF_VOID_P MATCHES "8")
+ #if that variable is not set check if we are on x86_64 and if so force it, else use default
+ add_flag_prepend(CMAKE_Pascal_FLAGS -Px86_64)
+ endif()
+
+ #CMAKE_OSX_SYSROOT is set at the system version we are supposed to build on
+ #we need to provide the correct one when host and target differ
if(NOT ${minimum_macosx_version} VERSION_EQUAL ${current_macosx_version})
if(minimum_macosx_version VERSION_EQUAL "10.4")
set(CMAKE_OSX_SYSROOT "/Developer/SDKs/MacOSX10.4u.sdk/")
@@ -65,19 +86,15 @@
string(REGEX REPLACE "([0-9]+.[0-9]+).[0-9]+" "\\1" sdk_version ${minimum_macosx_version})
set(CMAKE_OSX_SYSROOT "/Developer/SDKs/MacOSX${sdk_version}.sdk/")
endif()
+ add_flag_append(CMAKE_Pascal_FLAGS "-XR${CMAKE_OSX_SYSROOT}")
+ add_flag_append(CMAKE_Pascal_FLAGS "-k-macosx_version_min -k${minimum_macosx_version}")
endif()
-
-#add user framework directory, other paths can be passed via FPFLAGS
- list(APPEND pascal_flags "-Ff~/Library/Frameworks")
-#set deployment target
- list(APPEND pascal_flags "-k-macosx_version_min" "-k${minimum_macosx_version}" "-XR${CMAKE_OSX_SYSROOT}")
-
endif(APPLE)
if(MINGW)
#this flags prevents a few dll hell problems
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static-libgcc ")
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc ")
+ add_flag_append(CMAKE_C_FLAGS "-static-libgcc")
+ add_flag_append(CMAKE_CXX_FLAGS "-static-libgcc")
endif(MINGW)
if(WIN32)
--- a/cmake_modules/utils.cmake Mon Jul 01 22:28:42 2013 +0300
+++ b/cmake_modules/utils.cmake Mon Jul 01 23:23:22 2013 +0300
@@ -12,7 +12,7 @@
find_package(${_PKG_NAME})
string(TOUPPER ${_PKG_NAME} _PKG_NAME_UP)
if(NOT ${_PKG_NAME_UP}_FOUND)
- message(SEND_ERROR "Missing ${_PKG_NAME}! Rerun cmake with -D${_VAR_NAME}=1 to build without it.")
+ message(SEND_ERROR "Missing ${_PKG_NAME}! Rerun cmake with -D${_VAR_NAME}=1 to skip this error.")
endif(NOT ${_PKG_NAME_UP}_FOUND)
endmacro(find_package_or_disable _PKG_NAME _VAR_NAME)
--- a/gameServer/CoreTypes.hs Mon Jul 01 22:28:42 2013 +0300
+++ b/gameServer/CoreTypes.hs Mon Jul 01 23:23:22 2013 +0300
@@ -144,6 +144,7 @@
GameInfo
{
roundMsgs :: [B.ByteString],
+ lastFilteredTimedMsg :: Maybe B.ByteString,
leftTeams :: [B.ByteString],
teamsAtStart :: [TeamInfo],
teamsInGameNumber :: Int,
@@ -161,6 +162,7 @@
newGameInfo =
GameInfo
[]
+ Nothing
[]
data RoomInfo =
--- a/gameServer/EngineInteraction.hs Mon Jul 01 22:28:42 2013 +0300
+++ b/gameServer/EngineInteraction.hs Mon Jul 01 23:23:22 2013 +0300
@@ -32,17 +32,22 @@
splitMessages = L.unfoldr (\b -> if B.null b then Nothing else Just $ B.splitAt (1 + fromIntegral (BW.head b)) b)
-checkNetCmd :: B.ByteString -> (B.ByteString, B.ByteString)
+checkNetCmd :: B.ByteString -> (B.ByteString, B.ByteString, Maybe (Maybe B.ByteString))
checkNetCmd msg = check decoded
where
decoded = liftM (splitMessages . BW.pack) $ Base64.decode $ B.unpack msg
- check Nothing = (B.empty, B.empty)
- check (Just msgs) = let (a, b) = (filter isLegal msgs, filter isNonEmpty a) in (encode a, encode b)
+ check Nothing = (B.empty, B.empty, Nothing)
+ check (Just msgs) = let (a, b) = (filter isLegal msgs, filter isNonEmpty a) in (encode a, encode b, lft a)
encode = B.pack . Base64.encode . BW.unpack . B.concat
isLegal m = (B.length m > 1) && (flip Set.member legalMessages . B.head . B.tail $ m)
+ lft = foldr l Nothing
+ l m n = let m' = B.head $ B.tail m; tst = flip Set.member in
+ if not $ tst timedMessages m' then n
+ else if '+' /= m' then Just Nothing else Just $ Just m
isNonEmpty = (/=) '+' . B.head . B.tail
legalMessages = Set.fromList $ "M#+LlRrUuDdZzAaSjJ,sNpPwtghbc12345" ++ slotMessages
slotMessages = "\128\129\130\131\132\133\134\135\136\137\138"
+ timedMessages = Set.fromList $ "+LlRrUuDdZzAaSjJ,NpPwtgc12345" ++ slotMessages
replayToDemo :: [TeamInfo]
@@ -50,18 +55,18 @@
-> Map.Map B.ByteString [B.ByteString]
-> [B.ByteString]
-> [B.ByteString]
-replayToDemo teams mapParams params msgs = concat [
+replayToDemo ti mParams prms msgs = concat [
[em "TD"]
, maybeScript
, maybeMap
- , [eml ["etheme ", head $ params Map.! "THEME"]]
- , [eml ["eseed ", mapParams Map.! "SEED"]]
+ , [eml ["etheme ", head $ prms Map.! "THEME"]]
+ , [eml ["eseed ", mParams Map.! "SEED"]]
, [eml ["e$gmflags ", showB gameFlags]]
, schemeFlags
- , [eml ["e$template_filter ", mapParams Map.! "TEMPLATE"]]
+ , [eml ["e$template_filter ", mParams Map.! "TEMPLATE"]]
, [eml ["e$mapgen ", mapgen]]
, mapgenSpecific
- , concatMap teamSetup teams
+ , concatMap teamSetup ti
, msgs
, [em "!"]
]
@@ -69,13 +74,13 @@
em = toEngineMsg
eml = em . B.concat
mapGenTypes = ["+rnd+", "+maze+", "+drawn+"]
- maybeScript = let s = head $ params Map.! "SCRIPT" in if s == "Normal" then [] else [eml ["escript Scripts/Multiplayer/", s, ".lua"]]
- maybeMap = let m = mapParams Map.! "MAP" in if m `elem` mapGenTypes then [] else [eml ["emap ", m]]
- scheme = tail $ params Map.! "SCHEME"
- mapgen = mapParams Map.! "MAPGEN"
+ maybeScript = let s = head $ prms Map.! "SCRIPT" in if s == "Normal" then [] else [eml ["escript Scripts/Multiplayer/", s, ".lua"]]
+ maybeMap = let m = mParams Map.! "MAP" in if m `elem` mapGenTypes then [] else [eml ["emap ", m]]
+ scheme = tail $ prms Map.! "SCHEME"
+ mapgen = mParams Map.! "MAPGEN"
mapgenSpecific = case mapgen of
- "+maze+" -> [eml ["e$maze_size ", head $ params Map.! "MAZE_SIZE"]]
- "+drawn" -> drawnMapData . head $ params Map.! "DRAWNMAP"
+ "+maze+" -> [eml ["e$maze_size ", head $ prms Map.! "MAZE_SIZE"]]
+ "+drawn" -> drawnMapData . head $ prms Map.! "DRAWNMAP"
_ -> []
gameFlags :: Word32
gameFlags = foldl (\r (b, f) -> if b == "false" then r else r .|. f) 0 $ zip scheme gameFlagConsts
@@ -83,7 +88,7 @@
$ filter (\(_, (n, _)) -> not $ B.null n)
$ zip (drop (length gameFlagConsts) scheme) schemeParams
ammoStr :: B.ByteString
- ammoStr = head . tail $ params Map.! "AMMO"
+ ammoStr = head . tail $ prms Map.! "AMMO"
ammo = let l = B.length ammoStr `div` 4; ((a, b), (c, d)) = (B.splitAt l . fst &&& B.splitAt l . snd) . B.splitAt (l * 2) $ ammoStr in
(map (\(x, y) -> eml [x, " ", y]) $ zip ["eammloadt", "eammprob", "eammdelay", "eammreinf"] [a, b, c, d])
++ [em "eammstore" | scheme !! 14 == "true" || scheme !! 20 == "false"]
--- a/gameServer/HWProtoInRoomState.hs Mon Jul 01 22:28:42 2013 +0300
+++ b/gameServer/HWProtoInRoomState.hs Mon Jul 01 23:23:22 2013 +0300
@@ -217,11 +217,15 @@
if teamsInGame cl > 0 && (isJust $ gameInfo rm) && (not $ B.null legalMsgs) then
return $ AnswerClients chans ["EM", legalMsgs]
- : [ModifyRoom (\r -> r{gameInfo = liftM (\g -> g{roundMsgs = nonEmptyMsgs : roundMsgs g}) $ gameInfo r}) | not $ B.null nonEmptyMsgs]
+ : [ModifyRoom (\r -> r{gameInfo = liftM
+ (\g -> g{
+ roundMsgs = if B.null nonEmptyMsgs then roundMsgs g else nonEmptyMsgs : roundMsgs g
+ , lastFilteredTimedMsg = fromMaybe (lastFilteredTimedMsg g) lastFTMsg})
+ $ gameInfo r})]
else
return []
where
- (legalMsgs, nonEmptyMsgs) = checkNetCmd msg
+ (legalMsgs, nonEmptyMsgs, lastFTMsg) = checkNetCmd msg
handleCmd_inRoom ["ROUNDFINISHED", _] = do
--- a/gameServer/HWProtoLobbyState.hs Mon Jul 01 22:28:42 2013 +0300
+++ b/gameServer/HWProtoLobbyState.hs Mon Jul 01 23:23:22 2013 +0300
@@ -4,6 +4,7 @@
import Data.Maybe
import Data.List
import Control.Monad.Reader
+import qualified Data.ByteString.Char8 as B
--------------------------------------
import CoreTypes
import Actions
@@ -77,7 +78,7 @@
[Warning $ loc "No such room"]
else if isRestrictedJoins jRoom then
[Warning $ loc "Joining restricted"]
- else if isRegisteredOnly jRoom then
+ else if isRegisteredOnly jRoom && (B.null . webPassword $ cl) then
[Warning $ loc "Registered users only"]
else if isBanned then
[Warning $ loc "You are banned in this room"]
@@ -114,10 +115,13 @@
watchRound cl jRoom chans = if isNothing $ gameInfo jRoom then
[]
else
- [AnswerClients [sendChan cl] ["RUN_GAME"]
- , AnswerClients chans ["CLIENT_FLAGS", "+g", nick cl]
- , ModifyClient (\c -> c{isInGame = True})
- , AnswerClients [sendChan cl] $ "EM" : toEngineMsg "e$spectate 1" : (reverse . roundMsgs . fromJust . gameInfo $ jRoom)]
+ AnswerClients [sendChan cl] ["RUN_GAME"]
+ : AnswerClients chans ["CLIENT_FLAGS", "+g", nick cl]
+ : ModifyClient (\c -> c{isInGame = True})
+ : (AnswerClients [sendChan cl] $ "EM" : toEngineMsg "e$spectate 1" : (reverse . roundMsgs . fromJust . gameInfo $ jRoom))
+ : [AnswerClients [sendChan cl] $ "EM" : [fromJust msg] | isJust msg]
+ where
+ msg = lastFilteredTimedMsg . fromJust . gameInfo $ jRoom
handleCmd_lobby ["JOIN_ROOM", roomName] =
--- a/hedgewars/ArgParsers.inc Mon Jul 01 22:28:42 2013 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,356 +0,0 @@
-(*
- * Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- *)
-
-procedure GciEasterEgg;
-begin
- WriteLn(stdout, ' ');
- WriteLn(stdout, ' /\\\\\\\\\\\\ /\\\\\\\\\ /\\\\\\\\\\\ ');
- WriteLn(stdout, ' /\\\////////// /\\\//////// \/////\\\/// ');
- WriteLn(stdout, ' /\\\ /\\\/ \/\\\ ');
- WriteLn(stdout, ' \/\\\ /\\\\\\\ /\\\ \/\\\ ');
- WriteLn(stdout, ' \/\\\ \/////\\\ \/\\\ \/\\\ ');
- WriteLn(stdout, ' \/\\\ \/\\\ \//\\\ \/\\\ ');
- WriteLn(stdout, ' \/\\\ \/\\\ \///\\\ \/\\\ ');
- WriteLn(stdout, ' \/\\\\\\\\\\\\\/ \////\\\\\\\\\ /\\\\\\\\\\\ ');
- WriteLn(stdout, ' \///////////// \///////// \/////////// ');
- WriteLn(stdout, ' ');
- WriteLn(stdout, ' Command Line Parser Implementation by a Google Code-In Student ');
- WriteLn(stdout, ' ASCII Art easter egg idea by @sheepluva ');
- WriteLn(stdout, ' ');
-end;
-
-procedure DisplayUsage;
-begin
- WriteLn(stdout, 'Usage: hwengine <path to replay file> [options]');
- WriteLn(stdout, '');
- WriteLn(stdout, 'where [options] can be any of the following:');
- WriteLn(stdout, ' --prefix [path to folder]');
- WriteLn(stdout, ' --user-prefix [path to folder]');
- WriteLn(stdout, ' --locale [name of language file]');
- WriteLn(stdout, ' --nick [string]');
- WriteLn(stdout, ' --fullscreen-width [fullscreen width in pixels]');
- WriteLn(stdout, ' --fullscreen-height [fullscreen height in pixels]');
- WriteLn(stdout, ' --width [window width in pixels]');
- WriteLn(stdout, ' --height [window height in pixels]');
- WriteLn(stdout, ' --volume [sound level]');
- WriteLn(stdout, ' --frame-interval [milliseconds]');
- Writeln(stdout, ' --stereo [value]');
- WriteLn(stdout, ' --raw-quality [flags]');
- WriteLn(stdout, ' --low-quality');
- WriteLn(stdout, ' --nomusic');
- WriteLn(stdout, ' --nosound');
- WriteLn(stdout, ' --fullscreen');
- WriteLn(stdout, ' --showfps');
- WriteLn(stdout, ' --altdmg');
- WriteLn(stdout, ' --no-teamtag');
- WriteLn(stdout, ' --no-hogtag');
- WriteLn(stdout, ' --no-healthtag');
- WriteLn(stdout, ' --translucent-tags');
- WriteLn(stdout, ' --stats-only');
- WriteLn(stdout, ' --help');
- WriteLn(stdout, '');
- WriteLn(stdout, 'For more detailed help and examples go to:');
- WriteLn(stdout, 'http://code.google.com/p/hedgewars/wiki/CommandLineOptions');
- GameType:= gmtSyntax;
-end;
-
-procedure setDepth(var paramIndex: LongInt);
-begin
- WriteLn(stdout, 'WARNING: --depth is a deprecated command, which could be removed in a future version!');
- WriteLn(stdout, ' This option no longer does anything, please consider removing it');
- WriteLn(stdout, '');
- inc(ParamIndex);
-end;
-
-procedure statsOnlyGame;
-begin
- cOnlyStats:= true;
- cReducedQuality:= $FFFFFFFF xor rqLowRes;
- SetSound(false);
- SetMusic(false);
- SetVolume(0);
-end;
-
-procedure setIpcPort(port: LongInt; var wrongParameter:Boolean);
-begin
- if isInternal then
- ipcPort := port
- else
- begin
- WriteLn(stderr, 'ERROR: use of --port is not allowed');
- wrongParameter := true;
- end
-end;
-
-function parseNick(nick: String): String;
-begin
- if isInternal then
- parseNick:= DecodeBase64(nick)
- else
- parseNick:= nick;
-end;
-
-procedure setStereoMode(tmp: LongInt);
-begin
- GrayScale:= false;
-{$IFDEF USE_S3D_RENDERING}
- if (tmp > 6) and (tmp < 13) then
- begin
- // set the gray anaglyph rendering
- GrayScale:= true;
- cStereoMode:= TStereoMode(max(0, min(ord(high(TStereoMode)), tmp-6)))
- end
- else if tmp <= 6 then
- // set the fullcolor anaglyph
- cStereoMode:= TStereoMode(max(0, min(ord(high(TStereoMode)), tmp)))
- else
- // any other mode
- cStereoMode:= TStereoMode(max(0, min(ord(high(TStereoMode)), tmp-6)));
-{$ELSE}
- tmp:= tmp;
- cStereoMode:= smNone;
-{$ENDIF}
-end;
-
-procedure startVideoRecording(var paramIndex: LongInt);
-begin
- // Silence the hint that appears when USE_VIDEO_RECORDING is not defined
- paramIndex:= paramIndex;
-{$IFDEF USE_VIDEO_RECORDING}
- GameType:= gmtRecord;
- inc(paramIndex);
- cVideoFramerateNum:= StrToInt(ParamStr(paramIndex)); inc(paramIndex);
- cVideoFramerateDen:= StrToInt(ParamStr(paramIndex)); inc(paramIndex);
- RecPrefix:= ParamStr(paramIndex); inc(paramIndex);
- cAVFormat:= ParamStr(paramIndex); inc(paramIndex);
- cVideoCodec:= ParamStr(paramIndex); inc(paramIndex);
- cVideoQuality:= StrToInt(ParamStr(paramIndex)); inc(paramIndex);
- cAudioCodec:= ParamStr(paramIndex); inc(paramIndex);
-{$ENDIF}
-end;
-
-function getLongIntParameter(str:String; var paramIndex:LongInt; var wrongParameter:Boolean): LongInt;
-var tmpInt, c: LongInt;
-begin
- inc(paramIndex);
- val(str, tmpInt, c);
- wrongParameter:= c <> 0;
- if wrongParameter then
- WriteLn(stderr, 'ERROR: '+ParamStr(paramIndex-1)+' expects a number, you passed "'+str+'"');
- getLongIntParameter:= tmpInt;
-end;
-
-function getStringParameter(str:String; var paramIndex:LongInt; var wrongParameter:Boolean): String;
-begin
- inc(paramIndex);
- wrongParameter:= (str='') or (Copy(str,1,2) = '--');
- if wrongParameter then
- WriteLn(stderr, 'ERROR: '+ParamStr(paramIndex-1)+' expects a string, you passed "'+str+'"');
- getStringParameter:= str;
-end;
-
-
-procedure parseClassicParameter(cmdArray: Array of String; size:LongInt; var paramIndex:LongInt); Forward;
-
-function parseParameter(cmd:String; arg:String; var paramIndex:LongInt): Boolean;
-const videoArray: Array [1..5] of String = ('--fullscreen-width','--fullscreen-height', '--width', '--height', '--depth');
- audioArray: Array [1..3] of String = ('--volume','--nomusic','--nosound');
- otherArray: Array [1..3] of String = ('--locale','--fullscreen','--showfps');
- mediaArray: Array [1..10] of String = ('--fullscreen-width', '--fullscreen-height', '--width', '--height', '--depth', '--volume','--nomusic','--nosound','--locale','--fullscreen');
- allArray: Array [1..18] of String = ('--fullscreen-width','--fullscreen-height', '--width', '--height', '--depth','--volume','--nomusic','--nosound','--locale','--fullscreen','--showfps','--altdmg','--frame-interval','--low-quality','--no-teamtag','--no-hogtag','--no-healthtag','--translucent-tags');
- reallyAll: array[0..34] of shortstring = (
- '--prefix', '--user-prefix', '--locale', '--fullscreen-width', '--fullscreen-height', '--width',
- '--height', '--frame-interval', '--volume','--nomusic', '--nosound',
- '--fullscreen', '--showfps', '--altdmg', '--low-quality', '--raw-quality', '--stereo', '--nick',
- {deprecated} '--depth', '--set-video', '--set-audio', '--set-other', '--set-multimedia', '--set-everything',
- {internal} '--internal', '--port', '--recorder', '--landpreview',
- {misc} '--stats-only', '--gci', '--help','--no-teamtag','--no-hogtag','--no-healthtag','--translucent-tags');
-var cmdIndex: byte;
-begin
- parseParameter:= false;
- cmdIndex:= 0;
-
- //NOTE: Any update to the list of parameters must be reflected in the case statement below, the reallyAll array above,
- // the the DisplayUsage() procedure, the HWForm::getDemoArguments() function, and the online wiki
-
- while (cmdIndex <= High(reallyAll)) and (cmd <> reallyAll[cmdIndex]) do inc(cmdIndex);
- case cmdIndex of
- {--prefix} 0 : PathPrefix := getStringParameter (arg, paramIndex, parseParameter);
- {--user-prefix} 1 : UserPathPrefix := getStringParameter (arg, paramIndex, parseParameter);
- {--locale} 2 : cLocaleFName := getStringParameter (arg, paramIndex, parseParameter);
- {--fullscreen-width} 3 : cFullscreenWidth := max(getLongIntParameter(arg, paramIndex, parseParameter), cMinScreenWidth);
- {--fullscreen-height} 4 : cFullscreenHeight := max(getLongIntParameter(arg, paramIndex, parseParameter), cMinScreenHeight);
- {--width} 5 : cWindowedWidth := max(2 * (getLongIntParameter(arg, paramIndex, parseParameter) div 2), cMinScreenWidth);
- {--height} 6 : cWindowedHeight := max(2 * (getLongIntParameter(arg, paramIndex, parseParameter) div 2), cMinScreenHeight);
- {--frame-interval} 7 : cTimerInterval := getLongIntParameter(arg, paramIndex, parseParameter);
- {--volume} 8 : SetVolume ( max(getLongIntParameter(arg, paramIndex, parseParameter), 0) );
- {--nomusic} 9 : SetMusic ( false );
- {--nosound} 10 : SetSound ( false );
- {--fullscreen} 11 : cFullScreen := true;
- {--showfps} 12 : cShowFPS := true;
- {--altdmg} 13 : cAltDamage := true;
- {--low-quality} 14 : cReducedQuality := $FFFFFFFF xor rqLowRes;
- {--raw-quality} 15 : cReducedQuality := getLongIntParameter(arg, paramIndex, parseParameter);
- {--stereo} 16 : setStereoMode ( getLongIntParameter(arg, paramIndex, parseParameter) );
- {--nick} 17 : UserNick := parseNick( getStringParameter(arg, paramIndex, parseParameter) );
- {deprecated options}
- {--depth} 18 : setDepth(paramIndex);
- {--set-video} 19 : parseClassicParameter(videoArray,5,paramIndex);
- {--set-audio} 20 : parseClassicParameter(audioArray,3,paramIndex);
- {--set-other} 21 : parseClassicParameter(otherArray,3,paramIndex);
- {--set-multimedia} 22 : parseClassicParameter(mediaArray,10,paramIndex);
- {--set-everything} 23 : parseClassicParameter(allArray,14,paramIndex);
- {"internal" options}
- {--internal} 24 : {$IFDEF HWLIBRARY}isInternal:= true{$ENDIF};
- {--port} 25 : setIpcPort( getLongIntParameter(arg, paramIndex, parseParameter), parseParameter );
- {--recorder} 26 : startVideoRecording(paramIndex);
- {--landpreview} 27 : GameType := gmtLandPreview;
- {anything else}
- {--stats-only} 28 : statsOnlyGame();
- {--gci} 29 : GciEasterEgg();
- {--help} 30 : DisplayUsage();
- {--no-teamtag} 31 : cTagsMask := cTagsMask and not htTeamName;
- {--no-hogtag} 32 : cTagsMask := cTagsMask and not htName;
- {--no-healthtag} 33 : cTagsMask := cTagsMask and not htHealth;
- {--translucent-tags} 34 : cTagsMask := cTagsMask or htTransparent
- else
- begin
- //Asusme the first "non parameter" is the replay file, anything else is invalid
- if (recordFileName = '') and (Copy(cmd,1,2) <> '--') then
- recordFileName := cmd
- else
- begin
- WriteLn(stderr, '"'+cmd+'" is not a valid option');
- parseParameter:= true;
- end;
- end;
- end;
-end;
-
-procedure parseClassicParameter(cmdArray: Array of String; size:LongInt; var paramIndex:LongInt);
-var index, tmpInt: LongInt;
- isBool, isValid: Boolean;
- cmd, arg, newSyntax: String;
-begin
- WriteLn(stdout, 'WARNING: you are using a deprecated command, which could be removed in a future version!');
- WriteLn(stdout, ' Consider updating to the latest syntax, which is much more flexible!');
- WriteLn(stdout, ' Run `hwegine --help` to learn it!');
- WriteLn(stdout, '');
-
- index:= 0;
- tmpInt:= 1;
- while (index < size) do
- begin
- newSyntax:= '';
- inc(paramIndex);
- cmd:= cmdArray[index];
- arg:= ParamStr(paramIndex);
- isValid:= (cmd<>'--depth');
-
- // check if the parameter is a boolean one
- isBool:= (cmd = '--nomusic') or (cmd = '--nosound') or (cmd = '--fullscreen') or (cmd = '--showfps') or (cmd = '--altdmg') or (cmd = '--no-teamtag') or (cmd = '--no-hogtag') or (cmd = '--no-healthtag') or (cmd = '--translucent-tags');
- if isBool and (arg='0') then
- isValid:= false;
- if (cmd='--nomusic') or (cmd='--nosound') then
- isValid:= not isValid;
-
- if isValid then
- begin
- parseParameter(cmd, arg, tmpInt);
- newSyntax := newSyntax + cmd + ' ';
- if not isBool then
- newSyntax := newSyntax + arg + ' ';
- end;
- inc(index);
- end;
-
- WriteLn(stdout, 'Attempted to automatically convert to the new syntax:');
- WriteLn(stdout, newSyntax);
- WriteLn(stdout, '');
-end;
-
-procedure parseCommandLine{$IFDEF HWLIBRARY}(argc: LongInt; argv: PPChar){$ENDIF};
-var paramIndex: LongInt;
- paramTotal: LongInt;
- index, nextIndex: LongInt;
- wrongParameter: boolean;
-//var tmpInt: LongInt;
-begin
- paramIndex:= {$IFDEF HWLIBRARY}0{$ELSE}1{$ENDIF};
- paramTotal:= {$IFDEF HWLIBRARY}argc-1{$ELSE}ParamCount{$ENDIF}; //-1 because pascal enumeration is inclusive
- (*
- WriteLn(stdout, 'total parameters: ' + inttostr(paramTotal));
- tmpInt:= 0;
- while (tmpInt <= paramTotal) do
- begin
- WriteLn(stdout, inttostr(tmpInt) + ': ' + {$IFDEF HWLIBRARY}argv[tmpInt]{$ELSE}paramCount(tmpInt){$ENDIF});
- inc(tmpInt);
- end;
- *)
- wrongParameter:= false;
- while (paramIndex <= paramTotal) do
- begin
- // avoid going past the number of paramTotal (esp. w/ library)
- index:= paramIndex;
- if index = paramTotal then nextIndex:= index
- else nextIndex:= index+1;
- {$IFDEF HWLIBRARY}
- wrongParameter:= parseParameter( argv[index], argv[nextIndex], paramIndex);
- {$ELSE}
- wrongParameter:= parseParameter( ParamStr(index), ParamStr(nextIndex), paramIndex);
- {$ENDIF}
- inc(paramIndex);
- end;
- if wrongParameter = true then
- GameType:= gmtSyntax;
-end;
-
-{$IFNDEF HWLIBRARY}
-procedure GetParams;
-begin
- isInternal:= (ParamStr(1) = '--internal');
-
- UserPathPrefix := '.';
- PathPrefix := cDefaultPathPrefix;
- recordFileName := '';
- parseCommandLine();
-
- if (isInternal) and (ParamCount<=1) then
- begin
- WriteLn(stderr, '--internal should not be manually used');
- GameType := gmtSyntax;
- end;
-
- if (not isInternal) and (recordFileName = '') then
- begin
- WriteLn(stderr, 'You must specify a replay file');
- GameType := gmtSyntax;
- end
- else if (recordFileName <> '') then
- WriteLn(stdout, 'Attempting to play demo file "' + recordFilename + '"');
-
- if (GameType = gmtSyntax) then
- WriteLn(stderr, 'Please use --help to see possible arguments and their usage');
-
- (*
- WriteLn(stdout,'PathPrefix: ' + PathPrefix);
- WriteLn(stdout,'UserPathPrefix: ' + UserPathPrefix);
- *)
-end;
-{$ENDIF}
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hedgewars/ArgParsers.pas Mon Jul 01 23:23:22 2013 +0300
@@ -0,0 +1,369 @@
+(*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *)
+
+{$INCLUDE "options.inc"}
+
+unit ArgParsers;
+interface
+
+procedure GetParams;
+
+implementation
+uses uVariables, uTypes, uUtils, uSound, uConsts;
+var isInternal: Boolean;
+
+procedure GciEasterEgg;
+begin
+ WriteLn(stdout, ' ');
+ WriteLn(stdout, ' /\\\\\\\\\\\\ /\\\\\\\\\ /\\\\\\\\\\\ ');
+ WriteLn(stdout, ' /\\\////////// /\\\//////// \/////\\\/// ');
+ WriteLn(stdout, ' /\\\ /\\\/ \/\\\ ');
+ WriteLn(stdout, ' \/\\\ /\\\\\\\ /\\\ \/\\\ ');
+ WriteLn(stdout, ' \/\\\ \/////\\\ \/\\\ \/\\\ ');
+ WriteLn(stdout, ' \/\\\ \/\\\ \//\\\ \/\\\ ');
+ WriteLn(stdout, ' \/\\\ \/\\\ \///\\\ \/\\\ ');
+ WriteLn(stdout, ' \/\\\\\\\\\\\\\/ \////\\\\\\\\\ /\\\\\\\\\\\ ');
+ WriteLn(stdout, ' \///////////// \///////// \/////////// ');
+ WriteLn(stdout, ' ');
+ WriteLn(stdout, ' Command Line Parser Implementation by a Google Code-In Student ');
+ WriteLn(stdout, ' ASCII Art easter egg idea by @sheepluva ');
+ WriteLn(stdout, ' ');
+end;
+
+procedure DisplayUsage;
+begin
+ WriteLn(stdout, 'Usage: hwengine <path to replay file> [options]');
+ WriteLn(stdout, '');
+ WriteLn(stdout, 'where [options] can be any of the following:');
+ WriteLn(stdout, ' --prefix [path to folder]');
+ WriteLn(stdout, ' --user-prefix [path to folder]');
+ WriteLn(stdout, ' --locale [name of language file]');
+ WriteLn(stdout, ' --nick [string]');
+ WriteLn(stdout, ' --fullscreen-width [fullscreen width in pixels]');
+ WriteLn(stdout, ' --fullscreen-height [fullscreen height in pixels]');
+ WriteLn(stdout, ' --width [window width in pixels]');
+ WriteLn(stdout, ' --height [window height in pixels]');
+ WriteLn(stdout, ' --volume [sound level]');
+ WriteLn(stdout, ' --frame-interval [milliseconds]');
+ Writeln(stdout, ' --stereo [value]');
+ WriteLn(stdout, ' --raw-quality [flags]');
+ WriteLn(stdout, ' --low-quality');
+ WriteLn(stdout, ' --nomusic');
+ WriteLn(stdout, ' --nosound');
+ WriteLn(stdout, ' --fullscreen');
+ WriteLn(stdout, ' --showfps');
+ WriteLn(stdout, ' --altdmg');
+ WriteLn(stdout, ' --no-teamtag');
+ WriteLn(stdout, ' --no-hogtag');
+ WriteLn(stdout, ' --no-healthtag');
+ WriteLn(stdout, ' --translucent-tags');
+ WriteLn(stdout, ' --stats-only');
+ WriteLn(stdout, ' --help');
+ WriteLn(stdout, '');
+ WriteLn(stdout, 'For more detailed help and examples go to:');
+ WriteLn(stdout, 'http://code.google.com/p/hedgewars/wiki/CommandLineOptions');
+ GameType:= gmtSyntax;
+end;
+
+procedure setDepth(var paramIndex: LongInt);
+begin
+ WriteLn(stdout, 'WARNING: --depth is a deprecated command, which could be removed in a future version!');
+ WriteLn(stdout, ' This option no longer does anything, please consider removing it');
+ WriteLn(stdout, '');
+ inc(ParamIndex);
+end;
+
+procedure statsOnlyGame;
+begin
+ cOnlyStats:= true;
+ cReducedQuality:= $FFFFFFFF xor rqLowRes;
+ SetSound(false);
+ SetMusic(false);
+ SetVolume(0);
+end;
+
+procedure setIpcPort(port: LongInt; var wrongParameter:Boolean);
+begin
+ if isInternal then
+ ipcPort := port
+ else
+ begin
+ WriteLn(stderr, 'ERROR: use of --port is not allowed');
+ wrongParameter := true;
+ end
+end;
+
+function parseNick(nick: String): String;
+begin
+ if isInternal then
+ parseNick:= DecodeBase64(nick)
+ else
+ parseNick:= nick;
+end;
+
+procedure setStereoMode(tmp: LongInt);
+begin
+ GrayScale:= false;
+{$IFDEF USE_S3D_RENDERING}
+ if (tmp > 6) and (tmp < 13) then
+ begin
+ // set the gray anaglyph rendering
+ GrayScale:= true;
+ cStereoMode:= TStereoMode(max(0, min(ord(high(TStereoMode)), tmp-6)))
+ end
+ else if tmp <= 6 then
+ // set the fullcolor anaglyph
+ cStereoMode:= TStereoMode(max(0, min(ord(high(TStereoMode)), tmp)))
+ else
+ // any other mode
+ cStereoMode:= TStereoMode(max(0, min(ord(high(TStereoMode)), tmp-6)));
+{$ELSE}
+ tmp:= tmp;
+ cStereoMode:= smNone;
+{$ENDIF}
+end;
+
+procedure startVideoRecording(var paramIndex: LongInt);
+begin
+ // Silence the hint that appears when USE_VIDEO_RECORDING is not defined
+ paramIndex:= paramIndex;
+{$IFDEF USE_VIDEO_RECORDING}
+ GameType:= gmtRecord;
+ inc(paramIndex);
+ cVideoFramerateNum:= StrToInt(ParamStr(paramIndex)); inc(paramIndex);
+ cVideoFramerateDen:= StrToInt(ParamStr(paramIndex)); inc(paramIndex);
+ RecPrefix:= ParamStr(paramIndex); inc(paramIndex);
+ cAVFormat:= ParamStr(paramIndex); inc(paramIndex);
+ cVideoCodec:= ParamStr(paramIndex); inc(paramIndex);
+ cVideoQuality:= StrToInt(ParamStr(paramIndex)); inc(paramIndex);
+ cAudioCodec:= ParamStr(paramIndex); inc(paramIndex);
+{$ENDIF}
+end;
+
+function getLongIntParameter(str:String; var paramIndex:LongInt; var wrongParameter:Boolean): LongInt;
+var tmpInt, c: LongInt;
+begin
+ inc(paramIndex);
+ val(str, tmpInt, c);
+ wrongParameter:= c <> 0;
+ if wrongParameter then
+ WriteLn(stderr, 'ERROR: '+ParamStr(paramIndex-1)+' expects a number, you passed "'+str+'"');
+ getLongIntParameter:= tmpInt;
+end;
+
+function getStringParameter(str:String; var paramIndex:LongInt; var wrongParameter:Boolean): String;
+begin
+ inc(paramIndex);
+ wrongParameter:= (str='') or (Copy(str,1,2) = '--');
+ if wrongParameter then
+ WriteLn(stderr, 'ERROR: '+ParamStr(paramIndex-1)+' expects a string, you passed "'+str+'"');
+ getStringParameter:= str;
+end;
+
+
+procedure parseClassicParameter(cmdArray: Array of String; size:LongInt; var paramIndex:LongInt); Forward;
+
+function parseParameter(cmd:String; arg:String; var paramIndex:LongInt): Boolean;
+const videoArray: Array [1..5] of String = ('--fullscreen-width','--fullscreen-height', '--width', '--height', '--depth');
+ audioArray: Array [1..3] of String = ('--volume','--nomusic','--nosound');
+ otherArray: Array [1..3] of String = ('--locale','--fullscreen','--showfps');
+ mediaArray: Array [1..10] of String = ('--fullscreen-width', '--fullscreen-height', '--width', '--height', '--depth', '--volume','--nomusic','--nosound','--locale','--fullscreen');
+ allArray: Array [1..18] of String = ('--fullscreen-width','--fullscreen-height', '--width', '--height', '--depth','--volume','--nomusic','--nosound','--locale','--fullscreen','--showfps','--altdmg','--frame-interval','--low-quality','--no-teamtag','--no-hogtag','--no-healthtag','--translucent-tags');
+ reallyAll: array[0..34] of shortstring = (
+ '--prefix', '--user-prefix', '--locale', '--fullscreen-width', '--fullscreen-height', '--width',
+ '--height', '--frame-interval', '--volume','--nomusic', '--nosound',
+ '--fullscreen', '--showfps', '--altdmg', '--low-quality', '--raw-quality', '--stereo', '--nick',
+ {deprecated} '--depth', '--set-video', '--set-audio', '--set-other', '--set-multimedia', '--set-everything',
+ {internal} '--internal', '--port', '--recorder', '--landpreview',
+ {misc} '--stats-only', '--gci', '--help','--no-teamtag','--no-hogtag','--no-healthtag','--translucent-tags');
+var cmdIndex: byte;
+begin
+ parseParameter:= false;
+ cmdIndex:= 0;
+
+ //NOTE: Any update to the list of parameters must be reflected in the case statement below, the reallyAll array above,
+ // the the DisplayUsage() procedure, the HWForm::getDemoArguments() function, and the online wiki
+
+ while (cmdIndex <= High(reallyAll)) and (cmd <> reallyAll[cmdIndex]) do inc(cmdIndex);
+ case cmdIndex of
+ {--prefix} 0 : PathPrefix := getStringParameter (arg, paramIndex, parseParameter);
+ {--user-prefix} 1 : UserPathPrefix := getStringParameter (arg, paramIndex, parseParameter);
+ {--locale} 2 : cLocaleFName := getStringParameter (arg, paramIndex, parseParameter);
+ {--fullscreen-width} 3 : cFullscreenWidth := max(getLongIntParameter(arg, paramIndex, parseParameter), cMinScreenWidth);
+ {--fullscreen-height} 4 : cFullscreenHeight := max(getLongIntParameter(arg, paramIndex, parseParameter), cMinScreenHeight);
+ {--width} 5 : cWindowedWidth := max(2 * (getLongIntParameter(arg, paramIndex, parseParameter) div 2), cMinScreenWidth);
+ {--height} 6 : cWindowedHeight := max(2 * (getLongIntParameter(arg, paramIndex, parseParameter) div 2), cMinScreenHeight);
+ {--frame-interval} 7 : cTimerInterval := getLongIntParameter(arg, paramIndex, parseParameter);
+ {--volume} 8 : SetVolume ( max(getLongIntParameter(arg, paramIndex, parseParameter), 0) );
+ {--nomusic} 9 : SetMusic ( false );
+ {--nosound} 10 : SetSound ( false );
+ {--fullscreen} 11 : cFullScreen := true;
+ {--showfps} 12 : cShowFPS := true;
+ {--altdmg} 13 : cAltDamage := true;
+ {--low-quality} 14 : cReducedQuality := $FFFFFFFF xor rqLowRes;
+ {--raw-quality} 15 : cReducedQuality := getLongIntParameter(arg, paramIndex, parseParameter);
+ {--stereo} 16 : setStereoMode ( getLongIntParameter(arg, paramIndex, parseParameter) );
+ {--nick} 17 : UserNick := parseNick( getStringParameter(arg, paramIndex, parseParameter) );
+ {deprecated options}
+ {--depth} 18 : setDepth(paramIndex);
+ {--set-video} 19 : parseClassicParameter(videoArray,5,paramIndex);
+ {--set-audio} 20 : parseClassicParameter(audioArray,3,paramIndex);
+ {--set-other} 21 : parseClassicParameter(otherArray,3,paramIndex);
+ {--set-multimedia} 22 : parseClassicParameter(mediaArray,10,paramIndex);
+ {--set-everything} 23 : parseClassicParameter(allArray,14,paramIndex);
+ {"internal" options}
+ {--internal} 24 : {$IFDEF HWLIBRARY}isInternal:= true{$ENDIF};
+ {--port} 25 : setIpcPort( getLongIntParameter(arg, paramIndex, parseParameter), parseParameter );
+ {--recorder} 26 : startVideoRecording(paramIndex);
+ {--landpreview} 27 : GameType := gmtLandPreview;
+ {anything else}
+ {--stats-only} 28 : statsOnlyGame();
+ {--gci} 29 : GciEasterEgg();
+ {--help} 30 : DisplayUsage();
+ {--no-teamtag} 31 : cTagsMask := cTagsMask and not htTeamName;
+ {--no-hogtag} 32 : cTagsMask := cTagsMask and not htName;
+ {--no-healthtag} 33 : cTagsMask := cTagsMask and not htHealth;
+ {--translucent-tags} 34 : cTagsMask := cTagsMask or htTransparent
+ else
+ begin
+ //Asusme the first "non parameter" is the replay file, anything else is invalid
+ if (recordFileName = '') and (Copy(cmd,1,2) <> '--') then
+ recordFileName := cmd
+ else
+ begin
+ WriteLn(stderr, '"'+cmd+'" is not a valid option');
+ parseParameter:= true;
+ end;
+ end;
+ end;
+end;
+
+procedure parseClassicParameter(cmdArray: Array of String; size:LongInt; var paramIndex:LongInt);
+var index, tmpInt: LongInt;
+ isBool, isValid: Boolean;
+ cmd, arg, newSyntax: String;
+begin
+ WriteLn(stdout, 'WARNING: you are using a deprecated command, which could be removed in a future version!');
+ WriteLn(stdout, ' Consider updating to the latest syntax, which is much more flexible!');
+ WriteLn(stdout, ' Run `hwegine --help` to learn it!');
+ WriteLn(stdout, '');
+
+ index:= 0;
+ tmpInt:= 1;
+ while (index < size) do
+ begin
+ newSyntax:= '';
+ inc(paramIndex);
+ cmd:= cmdArray[index];
+ arg:= ParamStr(paramIndex);
+ isValid:= (cmd<>'--depth');
+
+ // check if the parameter is a boolean one
+ isBool:= (cmd = '--nomusic') or (cmd = '--nosound') or (cmd = '--fullscreen') or (cmd = '--showfps') or (cmd = '--altdmg') or (cmd = '--no-teamtag') or (cmd = '--no-hogtag') or (cmd = '--no-healthtag') or (cmd = '--translucent-tags');
+ if isBool and (arg='0') then
+ isValid:= false;
+ if (cmd='--nomusic') or (cmd='--nosound') then
+ isValid:= not isValid;
+
+ if isValid then
+ begin
+ parseParameter(cmd, arg, tmpInt);
+ newSyntax := newSyntax + cmd + ' ';
+ if not isBool then
+ newSyntax := newSyntax + arg + ' ';
+ end;
+ inc(index);
+ end;
+
+ WriteLn(stdout, 'Attempted to automatically convert to the new syntax:');
+ WriteLn(stdout, newSyntax);
+ WriteLn(stdout, '');
+end;
+
+procedure parseCommandLine{$IFDEF HWLIBRARY}(argc: LongInt; argv: PPChar){$ENDIF};
+var paramIndex: LongInt;
+ paramTotal: LongInt;
+ index, nextIndex: LongInt;
+ wrongParameter: boolean;
+//var tmpInt: LongInt;
+begin
+ paramIndex:= {$IFDEF HWLIBRARY}0{$ELSE}1{$ENDIF};
+ paramTotal:= {$IFDEF HWLIBRARY}argc-1{$ELSE}ParamCount{$ENDIF}; //-1 because pascal enumeration is inclusive
+ (*
+ WriteLn(stdout, 'total parameters: ' + inttostr(paramTotal));
+ tmpInt:= 0;
+ while (tmpInt <= paramTotal) do
+ begin
+ WriteLn(stdout, inttostr(tmpInt) + ': ' + {$IFDEF HWLIBRARY}argv[tmpInt]{$ELSE}paramCount(tmpInt){$ENDIF});
+ inc(tmpInt);
+ end;
+ *)
+ wrongParameter:= false;
+ while (paramIndex <= paramTotal) do
+ begin
+ // avoid going past the number of paramTotal (esp. w/ library)
+ index:= paramIndex;
+ if index = paramTotal then nextIndex:= index
+ else nextIndex:= index+1;
+ {$IFDEF HWLIBRARY}
+ wrongParameter:= parseParameter( argv[index], argv[nextIndex], paramIndex);
+ {$ELSE}
+ wrongParameter:= parseParameter( ParamStr(index), ParamStr(nextIndex), paramIndex);
+ {$ENDIF}
+ inc(paramIndex);
+ end;
+ if wrongParameter = true then
+ GameType:= gmtSyntax;
+end;
+
+{$IFNDEF HWLIBRARY}
+procedure GetParams;
+begin
+ isInternal:= (ParamStr(1) = '--internal');
+
+ UserPathPrefix := '.';
+ PathPrefix := cDefaultPathPrefix;
+ recordFileName := '';
+ parseCommandLine();
+
+ if (isInternal) and (ParamCount<=1) then
+ begin
+ WriteLn(stderr, '--internal should not be manually used');
+ GameType := gmtSyntax;
+ end;
+
+ if (not isInternal) and (recordFileName = '') then
+ begin
+ WriteLn(stderr, 'You must specify a replay file');
+ GameType := gmtSyntax;
+ end
+ else if (recordFileName <> '') then
+ WriteLn(stdout, 'Attempting to play demo file "' + recordFilename + '"');
+
+ if (GameType = gmtSyntax) then
+ WriteLn(stderr, 'Please use --help to see possible arguments and their usage');
+
+ (*
+ WriteLn(stdout,'PathPrefix: ' + PathPrefix);
+ WriteLn(stdout,'UserPathPrefix: ' + UserPathPrefix);
+ *)
+end;
+{$ENDIF}
+
+end.
+
--- a/hedgewars/CMakeLists.txt Mon Jul 01 22:28:42 2013 +0300
+++ b/hedgewars/CMakeLists.txt Mon Jul 01 23:23:22 2013 +0300
@@ -12,6 +12,7 @@
include_directories(${CMAKE_CURRENT_BINARY_DIR})
+#set the sources with the correct order of dependencies so that cmake won't be confused
set(engine_sources
SDLh.pas
uSinTable.pas
@@ -19,23 +20,22 @@
uConsts.pas
LuaPas.pas
uTypes.pas
+ uVariables.pas
uUtils.pas
- uVariables.pas
uMisc.pas
uConsole.pas
+ uCommands.pas
uDebug.pas
- uCommands.pas
uInputHandler.pas
uTextures.pas
uRenderUtils.pas
uRender.pas
uCaptions.pas
- uLandTexture.pas
uIO.pas
uChat.pas
uPhysFSLayer.pas
- uStore.pas
uSound.pas
+ ArgParsers.pas
uRandom.pas
uLocale.pas
uStats.pas
@@ -44,38 +44,44 @@
uAILandMarks.pas
adler32.pas
uLandTemplates.pas
+ uLandTexture.pas
uLandGraphics.pas
uLandPainted.pas
uLandOutline.pas
uLandGenMaze.pas
+
+ #this is where dependency tracking becomes hard
+ uStore.pas
+ uAmmos.pas
uLandObjects.pas
uLand.pas
- uAmmos.pas
-
+ uGearsList.pas
+ uCollisions.pas
uAIMisc.pas
uAIActions.pas
+ uAIAmmoTests.pas
uAI.pas
uWorld.pas
+ uVisualGearsList.pas
+ uVisualGearsHandlers.pas
uVisualGears.pas
- uTeams.pas
- uGearsList.pas
- uCollisions.pas
- uAIAmmoTests.pas
uGears.pas
uGame.pas
uCommandHandlers.pas
+ uGearsRender.pas
+ uGearsHedgehog.pas
uGearsHandlers.pas
uGearsHandlersRope.pas
- uGearsHedgehog.pas
- uGearsRender.pas
+ uGearsHandlersMess.pas
uGearsUtils.pas
+ uTeams.pas
+
+ #these interact with everything, so compile last
uScript.pas
hwengine.pas
- GSHandlers.inc
- VGSHandlers.inc
- ArgParsers.inc
+ #we also have uTouch.pas
options.inc
${CMAKE_CURRENT_BINARY_DIR}/config.inc
)
@@ -93,53 +99,25 @@
#DEPENDECIES AND EXECUTABLES SECTION
-if(APPLE)
- if(CMAKE_OSX_ARCHITECTURES)
- #parse this system variable and adjust only the powerpc syntax to be compatible with -P
- string(REGEX MATCH "[pP][pP][cC]+" powerpc_build "${CMAKE_OSX_ARCHITECTURES}")
- string(REGEX MATCH "[iI]386+" i386_build "${CMAKE_OSX_ARCHITECTURES}")
- string(REGEX MATCH "[xX]86_64+" x86_64_build "${CMAKE_OSX_ARCHITECTURES}")
- if(x86_64_build)
- add_flag_prepend(CMAKE_Pascal_FLAGS -Px86_64)
- elseif(i386_build)
- add_flag_prepend(CMAKE_Pascal_FLAGS -Pi386)
- elseif(powerpc_build)
- add_flag_prepend(CMAKE_Pascal_FLAGS -Ppowerpc)
- else()
- message(FATAL_ERROR "Unknown architecture present in CMAKE_OSX_ARCHITECTURES (${CMAKE_OSX_ARCHITECTURES})")
- endif()
- list(LENGTH CMAKE_OSX_ARCHITECTURES num_of_archs)
- if(num_of_archs GREATER 1)
- message(${WARNING} "Only one architecture in CMAKE_OSX_ARCHITECTURES is currently supported, picking the first one")
- endif()
- elseif(CMAKE_SIZEOF_VOID_P MATCHES "8")
- #if that variable is not set check if we are on x86_64 and if so force it, else use default
- add_flag_prepend(CMAKE_Pascal_FLAGS -Px86_64)
- endif()
-
+if(NOT ${BUILD_ENGINE_LIBRARY} AND APPLE)
#on OSX we need to provide the SDL_main() function when building as executable
- if(NOT BUILD_ENGINE_LIBRARY)
- add_subdirectory(sdlmain)
- list(APPEND HW_LINK_LIBS SDLmain)
- add_flag_append(CMAKE_Pascal_FLAGS -Fl${LIBRARY_OUTPUT_PATH})
- endif()
-
- #when sysroot is set, make sure that fpc picks it
- if(CMAKE_OSX_SYSROOT)
- set(add_flag_append "-XD${CMAKE_OSX_SYSROOT}")
- endif(CMAKE_OSX_SYSROOT)
-endif(APPLE)
+ add_subdirectory(sdlmain)
+ list(APPEND HW_LINK_LIBS SDLmain)
+ add_flag_append(CMAKE_Pascal_FLAGS -Fl${LIBRARY_OUTPUT_PATH})
+endif()
if(FFMPEG_FOUND)
add_subdirectory(avwrapper)
list(APPEND HW_LINK_LIBS avwrapper)
add_definitions(-dUSE_VIDEO_RECORDING)
add_flag_append(CMAKE_Pascal_FLAGS -Fl${LIBRARY_OUTPUT_PATH})
+ #only for SDL < 2, linking carried out by fpc
+ find_package_or_disable_msg(GLUT NOVIDEOREC "Video recording will not be built")
endif()
find_package_or_disable_msg(PNG NOPNG "Screenshots will be saved in BMP")
if(PNG_FOUND)
- list(APPEND engine_sources PNGh.pas)
+ list(INSERT engine_sources 0 PNGh.pas)
list(REMOVE_AT PNG_LIBRARIES 1) #removing the zlib library path
get_filename_component(PNG_LIBRARY_DIR ${PNG_LIBRARIES} PATH)
add_flag_append(CMAKE_Pascal_FLAGS -Fl${PNG_LIBRARY_DIR})
--- a/hedgewars/GSHandlers.inc Mon Jul 01 22:28:42 2013 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,5638 +0,0 @@
-(*
- * Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- *)
-
-(*
- * This file contains the step handlers for gears.
- *
- * Important: Since gears change the course of the game, calculations that
- * lead to different results for different clients/players/machines
- * should NOT occur!
- * Use safe functions and data types! (e.g. GetRandom() and hwFloat)
- *)
-
-procedure doStepPerPixel(Gear: PGear; step: TGearStepProcedure; onlyCheckIfChanged: boolean);
-var
- dX, dY, sX, sY: hwFloat;
- i, steps: LongWord;
- caller: TGearStepProcedure;
-begin
- dX:= Gear^.dX;
- dY:= Gear^.dY;
- steps:= max(abs(hwRound(Gear^.X+dX)-hwRound(Gear^.X)), abs(hwRound(Gear^.Y+dY)-hwRound(Gear^.Y)));
-
- // Gear is still on the same Pixel it was before
- if steps < 1 then
- begin
- if onlyCheckIfChanged then
- begin
- Gear^.X := Gear^.X + dX;
- Gear^.Y := Gear^.Y + dY;
- EXIT;
- end
- else
- steps := 1;
- end;
-
- if steps > 1 then
- begin
- sX:= dX / steps;
- sY:= dY / steps;
- end
-
- else
- begin
- sX:= dX;
- sY:= dY;
- end;
-
- caller:= Gear^.doStep;
-
- for i:= 1 to steps do
- begin
- Gear^.X := Gear^.X + sX;
- Gear^.Y := Gear^.Y + sY;
- step(Gear);
- if (Gear^.doStep <> caller)
- or ((Gear^.State and gstCollision) <> 0)
- or ((Gear^.State and gstMoving) = 0) then
- break;
- end;
-end;
-
-procedure makeHogsWorry(x, y: hwFloat; r: LongInt);
-var
- gi: PGear;
- d: LongInt;
-begin
- gi := GearsList;
- while gi <> nil do
- begin
- if (gi^.Kind = gtHedgehog) then
- begin
- d := r - hwRound(Distance(gi^.X - x, gi^.Y - y));
- if (d > 1) and (not gi^.Invulnerable) and (GetRandom(2) = 0) then
- begin
- if (CurrentHedgehog^.Gear = gi) then
- PlaySoundV(sndOops, gi^.Hedgehog^.Team^.voicepack)
-
- else
- begin
- if ((gi^.State and gstMoving) = 0) and (gi^.Hedgehog^.Effects[heFrozen] = 0) then
- begin
- gi^.dX.isNegative:= X<gi^.X;
- gi^.State := gi^.State or gstLoser;
- end;
-
- if d > r div 2 then
- PlaySoundV(sndNooo, gi^.Hedgehog^.Team^.voicepack)
- else
- PlaySoundV(sndUhOh, gi^.Hedgehog^.Team^.voicepack);
- end;
- end;
- end;
-
- gi := gi^.NextGear
- end;
-end;
-
-procedure HideHog(HH: PHedgehog);
-begin
- ScriptCall('onHogHide', HH^.Gear^.Uid);
- DeleteCI(HH^.Gear);
- if FollowGear = HH^.Gear then
- FollowGear:= nil;
-
- if lastGearByUID = HH^.Gear then
- lastGearByUID := nil;
-
- HH^.Gear^.Message:= HH^.Gear^.Message or gmRemoveFromList;
- with HH^.Gear^ do
- begin
- Z := cHHZ;
- HH^.Gear^.Active:= false;
- State:= State and (not (gstHHDriven or gstAttacking or gstAttacked));
- Message := Message and (not gmAttack);
- end;
- HH^.GearHidden:= HH^.Gear;
- HH^.Gear:= nil
-end;
-
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepDrowningGear(Gear: PGear);
- begin
- AllInactive := false;
- Gear^.Y := Gear^.Y + cDrownSpeed;
- Gear^.X := Gear^.X + Gear^.dX * cDrownSpeed;
- // Create some bubbles (0.5% might be better but causes too few bubbles sometimes)
- if ((not SuddenDeathDmg and (WaterOpacity < $FF))
- or (SuddenDeathDmg and (SDWaterOpacity < $FF))) and ((GameTicks and $1F) = 0) then
- if (Gear^.Kind = gtHedgehog) and (Random(4) = 0) then
- AddVisualGear(hwRound(Gear^.X) - Gear^.Radius, hwRound(Gear^.Y) - Gear^.Radius, vgtBubble)
- else if Random(12) = 0 then
- AddVisualGear(hwRound(Gear^.X) - Gear^.Radius, hwRound(Gear^.Y) - Gear^.Radius, vgtBubble);
- if (not SuddenDeathDmg and (WaterOpacity > $FE))
- or (SuddenDeathDmg and (SDWaterOpacity > $FE))
- or (hwRound(Gear^.Y) > Gear^.Radius + cWaterLine + cVisibleWater) then
- DeleteGear(Gear);
- end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepFallingGear(Gear: PGear);
-var
- isFalling: boolean;
- //tmp: QWord;
- tdX, tdY: hwFloat;
- collV, collH: LongInt;
- land: word;
-begin
- // clip velocity at 2 - over 1 per pixel, but really shouldn't cause many actual problems.
- if Gear^.dX.Round > 2 then
- Gear^.dX.QWordValue:= 8589934592;
- if Gear^.dY.Round > 2 then
- Gear^.dY.QWordValue:= 8589934592;
-
- if (Gear^.State and gstSubmersible <> 0) and (hwRound(Gear^.Y) > cWaterLine) then
- begin
- Gear^.dX:= Gear^.dX * _0_999;
- Gear^.dY:= Gear^.dY * _0_999
- end;
-
- Gear^.State := Gear^.State and (not gstCollision);
- collV := 0;
- collH := 0;
- tdX := Gear^.dX;
- tdY := Gear^.dY;
-
-
-
-// might need some testing/adjustments - just to avoid projectiles to fly forever (accelerated by wind/skips)
- if (hwRound(Gear^.X) < min(LAND_WIDTH div -2, -2048))
- or (hwRound(Gear^.X) > max(LAND_WIDTH * 3 div 2, 6144)) then
- Gear^.State := Gear^.State or gstCollision;
-
- if Gear^.dY.isNegative then
- begin
- isFalling := true;
- land:= TestCollisionYwithGear(Gear, -1);
- if land <> 0 then
- begin
- collV := -1;
- if land and lfIce <> 0 then
- Gear^.dX := Gear^.dX * (_0_9 + Gear^.Friction * _0_1)
- else
- Gear^.dX := Gear^.dX * Gear^.Friction;
-
- Gear^.dY := - Gear^.dY * Gear^.Elasticity;
- Gear^.State := Gear^.State or gstCollision
- end
- else if (Gear^.AdvBounce=1) and (TestCollisionYwithGear(Gear, 1) <> 0) then
- collV := 1;
- end
- else
- begin // Gear^.dY.isNegative is false
- land:= TestCollisionYwithGear(Gear, 1);
- if land <> 0 then
- begin
- collV := 1;
- isFalling := false;
- if land and lfIce <> 0 then
- Gear^.dX := Gear^.dX * (_0_9 + Gear^.Friction * _0_1)
- else
- Gear^.dX := Gear^.dX * Gear^.Friction;
-
- Gear^.dY := - Gear^.dY * Gear^.Elasticity;
- Gear^.State := Gear^.State or gstCollision
- end
- else
- begin
- isFalling := true;
- if (Gear^.AdvBounce=1) and (TestCollisionYwithGear(Gear, -1) <> 0) then
- collV := -1
- end
- end;
-
-
- if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then
- begin
- collH := hwSign(Gear^.dX);
- Gear^.dX := - Gear^.dX * Gear^.Elasticity;
- Gear^.dY := Gear^.dY * Gear^.Elasticity;
- Gear^.State := Gear^.State or gstCollision
- end
- else if (Gear^.AdvBounce=1) and TestCollisionXwithGear(Gear, -hwSign(Gear^.dX)) then
- collH := -hwSign(Gear^.dX);
- //if Gear^.AdvBounce and (collV <>0) and (collH <> 0) and (hwSqr(tdX) + hwSqr(tdY) > _0_08) then
- if (Gear^.AdvBounce=1) and (collV <>0) and (collH <> 0) and ((collV=-1)
- or ((tdX.QWordValue + tdY.QWordValue) > _0_2.QWordValue)) then
- begin
- Gear^.dX := tdY*Gear^.Elasticity*Gear^.Friction;
- Gear^.dY := tdX*Gear^.Elasticity;
- //*Gear^.Friction;
- Gear^.dY.isNegative := not tdY.isNegative;
- isFalling := false;
- Gear^.AdvBounce := 10;
- end;
-
- if Gear^.AdvBounce > 1 then
- dec(Gear^.AdvBounce);
-
- if isFalling then
- begin
- Gear^.dY := Gear^.dY + cGravity;
- if (GameFlags and gfMoreWind) <> 0 then
- Gear^.dX := Gear^.dX + cWindSpeed / Gear^.Density
- end;
-
- Gear^.X := Gear^.X + Gear^.dX;
- Gear^.Y := Gear^.Y + Gear^.dY;
- if Gear^.Kind <> gtBee then
- CheckGearDrowning(Gear);
- //if (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) < _0_0002) and
- if (not isFalling) and ((Gear^.dX.QWordValue + Gear^.dY.QWordValue) < _0_02.QWordValue) then
- Gear^.State := Gear^.State and (not gstMoving)
- else
- Gear^.State := Gear^.State or gstMoving;
-
- if (Gear^.nImpactSounds > 0) and
- (Gear^.State and gstCollision <> 0) and
- (((Gear^.Kind <> gtMine) and (Gear^.Damage <> 0)) or (Gear^.State and gstMoving <> 0)) and
- (((Gear^.Radius < 3) and (Gear^.dY < -_0_1)) or
- ((Gear^.Radius >= 3) and
- ((Gear^.dX.QWordValue > _0_1.QWordValue) or (Gear^.dY.QWordValue > _0_1.QWordValue)))) then
- PlaySound(TSound(ord(Gear^.ImpactSound) + LongInt(GetRandom(Gear^.nImpactSounds))), true);
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepBomb(Gear: PGear);
-var
- i, x, y: LongInt;
- dX, dY, gdX: hwFloat;
- vg: PVisualGear;
-begin
- AllInactive := false;
-
- doStepFallingGear(Gear);
-
- dec(Gear^.Timer);
- if Gear^.Timer = 1000 then // might need adjustments
- case Gear^.Kind of
- gtGrenade: makeHogsWorry(Gear^.X, Gear^.Y, 50);
- gtClusterBomb: makeHogsWorry(Gear^.X, Gear^.Y, 20);
- gtWatermelon: makeHogsWorry(Gear^.X, Gear^.Y, 75);
- gtHellishBomb: makeHogsWorry(Gear^.X, Gear^.Y, 90);
- gtGasBomb: makeHogsWorry(Gear^.X, Gear^.Y, 50);
- end;
-
- if (Gear^.Kind = gtBall) and ((Gear^.State and gstTmpFlag) <> 0) then
- begin
- CheckCollision(Gear);
- if (Gear^.State and gstCollision) <> 0 then
- doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 20, Gear^.Hedgehog, EXPLDontDraw or EXPLNoGfx);
- end;
-
- if (Gear^.Kind = gtGasBomb) and ((GameTicks mod 200) = 0) then
- begin
- vg:= AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeWhite);
- if vg <> nil then
- vg^.Tint:= $FFC0C000;
- end;
-
- if Gear^.Timer = 0 then
- begin
- case Gear^.Kind of
- gtGrenade: doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound);
- gtBall: doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 40, Gear^.Hedgehog, EXPLAutoSound);
- gtClusterBomb:
- begin
- x := hwRound(Gear^.X);
- y := hwRound(Gear^.Y);
- gdX:= Gear^.dX;
- doMakeExplosion(x, y, 20, Gear^.Hedgehog, EXPLAutoSound);
- for i:= 0 to 4 do
- begin
- dX := rndSign(GetRandomf * _0_1) + gdX / 5;
- dY := (GetRandomf - _3) * _0_08;
- FollowGear := AddGear(x, y, gtCluster, 0, dX, dY, 25)
- end
- end;
- gtWatermelon:
- begin
- x := hwRound(Gear^.X);
- y := hwRound(Gear^.Y);
- gdX:= Gear^.dX;
- doMakeExplosion(x, y, 75, Gear^.Hedgehog, EXPLAutoSound);
- for i:= 0 to 5 do
- begin
- dX := rndSign(GetRandomf * _0_1) + gdX / 5;
- dY := (GetRandomf - _1_5) * _0_3;
- FollowGear:= AddGear(x, y, gtMelonPiece, 0, dX, dY, 75);
- FollowGear^.DirAngle := i * 60
- end
- end;
- gtHellishBomb:
- begin
- x := hwRound(Gear^.X);
- y := hwRound(Gear^.Y);
- doMakeExplosion(x, y, 90, Gear^.Hedgehog, EXPLAutoSound);
-
- for i:= 0 to 127 do
- begin
- dX := AngleCos(i * 16) * _0_5 * (GetRandomf + _1);
- dY := AngleSin(i * 16) * _0_5 * (GetRandomf + _1);
- if i mod 2 = 0 then
- begin
- AddGear(x, y, gtFlame, gstTmpFlag, dX, dY, 0);
- AddGear(x, y, gtFlame, 0, dX, -dY, 0)
- end
- else
- begin
- AddGear(x, y, gtFlame, 0, dX, dY, 0);
- AddGear(x, y, gtFlame, gstTmpFlag, dX, -dY, 0)
- end;
- end
- end;
- gtGasBomb:
- begin
- doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 20, Gear^.Hedgehog, EXPLAutoSound);
- for i:= 0 to 2 do
- begin
- x:= GetRandom(60);
- y:= GetRandom(40);
- FollowGear:= AddGear(hwRound(Gear^.X) - 30 + x, hwRound(Gear^.Y) - 20 + y, gtPoisonCloud, 0, _0, _0, 0);
- end
- end;
- end;
- DeleteGear(Gear);
- exit
- end;
-
- CalcRotationDirAngle(Gear);
-
- if Gear^.Kind = gtHellishBomb then
- begin
-
- if Gear^.Timer = 3000 then
- begin
- Gear^.nImpactSounds := 0;
- PlaySound(sndHellish);
- end;
-
- if (GameTicks and $3F) = 0 then
- if (Gear^.State and gstCollision) = 0 then
- AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtEvilTrace);
- end;
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepMolotov(Gear: PGear);
-var
- s: Longword;
- i, gX, gY: LongInt;
- dX, dY: hwFloat;
- smoke, glass: PVisualGear;
-begin
- AllInactive := false;
-
- doStepFallingGear(Gear);
- CalcRotationDirAngle(Gear);
-
- // let's add some smoke depending on speed
- s:= max(32,152 - round((abs(hwFloat2FLoat(Gear^.dX))+abs(hwFloat2Float(Gear^.dY)))*120))+random(10);
- if (GameTicks mod s) = 0 then
- begin
- // adjust angle to match the texture
- if Gear^.dX.isNegative then
- i:= 130
- else i:= 50;
-
- smoke:= AddVisualGear(hwRound(Gear^.X)-round(cos((Gear^.DirAngle+i) * pi / 180)*20), hwRound(Gear^.Y)-round(sin((Gear^.DirAngle+i) * pi / 180)*20), vgtSmoke);
- if smoke <> nil then
- smoke^.Scale:= 0.75;
- end;
-
- if (Gear^.State and gstCollision) <> 0 then
- begin
- PlaySound(sndMolotov);
- gX := hwRound(Gear^.X);
- gY := hwRound(Gear^.Y);
- for i:= 0 to 4 do
- begin
- (*glass:= AddVisualGear(gx+random(7)-3, gy+random(5)-2, vgtEgg);
- if glass <> nil then
- begin
- glass^.Frame:= 2;
- glass^.Tint:= $41B83ED0 - i * $10081000;
- glass^.dX:= 1/(10*(random(11)-5));
- glass^.dY:= -1/(random(4)+5);
- end;*)
- glass:= AddVisualGear(gx+random(7)-3, gy+random(7)-3, vgtStraightShot);
- if glass <> nil then
- with glass^ do
- begin
- Frame:= 2;
- Tint:= $41B83ED0 - i * $10081000;
- Angle:= random(360);
- dx:= 0.0000001;
- dy:= 0;
- if random(2) = 0 then
- dx := -dx;
- FrameTicks:= 750;
- State:= ord(sprEgg)
- end;
- end;
- for i:= 0 to 24 do
- begin
- dX := AngleCos(i * 2) * ((_0_15*(i div 5))) * (GetRandomf + _1);
- dY := AngleSin(i * 8) * _0_5 * (GetRandomf + _1);
- AddGear(gX, gY, gtFlame, gstTmpFlag, dX, dY, 0);
- AddGear(gX, gY, gtFlame, gstTmpFlag, dX,-dY, 0);
- AddGear(gX, gY, gtFlame, gstTmpFlag,-dX, dY, 0);
- AddGear(gX, gY, gtFlame, gstTmpFlag,-dX,-dY, 0);
- end;
- DeleteGear(Gear);
- exit
- end;
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-
-procedure doStepCluster(Gear: PGear);
-begin
- AllInactive := false;
- doStepFallingGear(Gear);
- if (Gear^.State and gstCollision) <> 0 then
- begin
- doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Timer, Gear^.Hedgehog, EXPLAutoSound);
- DeleteGear(Gear);
- exit
- end;
-
- if (Gear^.Kind = gtMelonPiece)
- or (Gear^.Kind = gtBall) then
- CalcRotationDirAngle(Gear)
- else if (GameTicks and $1F) = 0 then
- begin
- if hwRound(Gear^.Y) > cWaterLine then
- AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtBubble)
- else AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace)
- end
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepShell(Gear: PGear);
-begin
- AllInactive := false;
- if (GameFlags and gfMoreWind) = 0 then
- Gear^.dX := Gear^.dX + cWindSpeed;
- doStepFallingGear(Gear);
- if (Gear^.State and gstCollision) <> 0 then
- begin
- doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound);
- DeleteGear(Gear);
- exit
- end;
- if (GameTicks and $3F) = 0 then
- begin
- if hwRound(Gear^.Y) > cWaterLine then
- AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtBubble)
- else AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace)
- end
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepSnowball(Gear: PGear);
-var kick, i: LongInt;
- particle: PVisualGear;
- gdX, gdY: hwFloat;
-begin
- AllInactive := false;
- if (GameFlags and gfMoreWind) = 0 then
- Gear^.dX := Gear^.dX + cWindSpeed;
- gdX := Gear^.dX;
- gdY := Gear^.dY;
- doStepFallingGear(Gear);
- CalcRotationDirAngle(Gear);
- if (Gear^.State and gstCollision) <> 0 then
- begin
- kick:= hwRound((hwAbs(gdX)+hwAbs(gdY)) * _20);
- Gear^.dX:= gdX;
- Gear^.dY:= gdY;
- AmmoShove(Gear, 0, kick);
- for i:= 15 + kick div 10 downto 0 do
- begin
- particle := AddVisualGear(hwRound(Gear^.X) + Random(25), hwRound(Gear^.Y) + Random(25), vgtDust);
- if particle <> nil then
- particle^.dX := particle^.dX + (Gear^.dX.QWordValue / 21474836480)
- end;
- DeleteGear(Gear);
- exit
- end;
- if ((GameTicks and $1F) = 0) and (Random(3) = 0) then
- begin
- particle:= AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtDust);
- if particle <> nil then
- particle^.dX := particle^.dX + (Gear^.dX.QWordValue / 21474836480)
- end
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepSnowflake(Gear: PGear);
-var xx, yy, px, py, rx, ry, lx, ly: LongInt;
- move, draw, allpx, gun: Boolean;
- s: PSDL_Surface;
- p: PLongwordArray;
- lf: LongWord;
-begin
-inc(Gear^.Pos);
-gun:= (Gear^.State and gstTmpFlag) <> 0;
-move:= false;
-draw:= false;
-if gun then
- begin
- Gear^.State:= Gear^.State and (not gstInvisible);
- doStepFallingGear(Gear);
- CheckCollision(Gear);
- if ((Gear^.State and gstCollision) <> 0) or ((Gear^.State and gstMoving) = 0) then
- draw:= true;
- xx:= hwRound(Gear^.X);
- yy:= hwRound(Gear^.Y);
- end
-else if GameTicks and $7 = 0 then
- begin
- with Gear^ do
- begin
- State:= State and (not gstInvisible);
- X:= X + cWindSpeed * 3200 + dX;
- Y:= Y + dY + cGravity * vobFallSpeed * 8; // using same value as flakes to try and get similar results
- xx:= hwRound(X);
- yy:= hwRound(Y);
- if vobVelocity <> 0 then
- begin
- DirAngle := DirAngle + (Damage / 1000);
- if DirAngle < 0 then
- DirAngle := DirAngle + 360
- else if 360 < DirAngle then
- DirAngle := DirAngle - 360;
- end;
-(*
-We aren't using frametick right now, so just a waste of cycles.
- inc(Health, 8);
- if longword(Health) > vobFrameTicks then
- begin
- dec(Health, vobFrameTicks);
- inc(Timer);
- if Timer = vobFramesCount then
- Timer:= 0
- end;
-*)
- // move back to cloud layer
- if yy > cWaterLine then
- move:= true
- else if (xx > snowRight) or (xx < snowLeft) then
- move:=true
- // Solid pixel encountered
- else if ((yy and LAND_HEIGHT_MASK) = 0) and ((xx and LAND_WIDTH_MASK) = 0) and (Land[yy, xx] <> 0) then
- begin
- lf:= Land[yy, xx] and (lfObject or lfBasic or lfIndestructible);
- if lf = 0 then lf:= lfObject;
- // If there's room below keep falling
- if (((yy-1) and LAND_HEIGHT_MASK) = 0) and (Land[yy-1, xx] = 0) then
- begin
- X:= X - cWindSpeed * 1600 - dX;
- end
- // If there's room below, on the sides, fill the gaps
- else if (((yy-1) and LAND_HEIGHT_MASK) = 0) and (((xx-(1*hwSign(cWindSpeed))) and LAND_WIDTH_MASK) = 0) and (Land[yy-1, (xx-(1*hwSign(cWindSpeed)))] = 0) then
- begin
- X:= X - _0_8 * hwSign(cWindSpeed);
- Y:= Y - dY - cGravity * vobFallSpeed * 8;
- end
- else if (((yy-1) and LAND_HEIGHT_MASK) = 0) and (((xx-(2*hwSign(cWindSpeed))) and LAND_WIDTH_MASK) = 0) and (Land[yy-1, (xx-(2*hwSign(cWindSpeed)))] = 0) then
- begin
- X:= X - _0_8 * 2 * hwSign(cWindSpeed);
- Y:= Y - dY - cGravity * vobFallSpeed * 8;
- end
- else if (((yy-1) and LAND_HEIGHT_MASK) = 0) and (((xx+(1*hwSign(cWindSpeed))) and LAND_WIDTH_MASK) = 0) and (Land[yy-1, (xx+(1*hwSign(cWindSpeed)))] = 0) then
- begin
- X:= X + _0_8 * hwSign(cWindSpeed);
- Y:= Y - dY - cGravity * vobFallSpeed * 8;
- end
- else if (((yy-1) and LAND_HEIGHT_MASK) = 0) and (((xx+(2*hwSign(cWindSpeed))) and LAND_WIDTH_MASK) = 0) and (Land[yy-1, (xx+(2*hwSign(cWindSpeed)))] = 0) then
- begin
- X:= X + _0_8 * 2 * hwSign(cWindSpeed);
- Y:= Y - dY - cGravity * vobFallSpeed * 8;
- end
- // if there's an hog/object below do nothing
- else if ((((yy+1) and LAND_HEIGHT_MASK) = 0) and ((Land[yy+1, xx] and $FF) <> 0))
- then move:=true
- else draw:= true
- end
- end
- end;
-if draw then
- with Gear^ do
- begin
- // we've collided with land. draw some stuff and get back into the clouds
- move:= true;
- if (Pos > 20) and ((CurAmmoGear = nil)
- or (CurAmmoGear^.Kind <> gtRope)) then
- begin
-////////////////////////////////// TODO - ASK UNC0RR FOR A GOOD HOME FOR THIS ////////////////////////////////////
- if not gun then
- begin
- dec(yy,3);
- dec(xx,1)
- end;
- s:= SpritesData[sprSnow].Surface;
- p:= s^.pixels;
- allpx:= true;
- for py:= 0 to Pred(s^.h) do
- begin
- for px:= 0 to Pred(s^.w) do
- begin
- lx:=xx + px; ly:=yy + py;
- if (ly and LAND_HEIGHT_MASK = 0) and (lx and LAND_WIDTH_MASK = 0) and (Land[ly, lx] and $FF = 0) then
- begin
- rx:= lx;
- ry:= ly;
- if cReducedQuality and rqBlurryLand <> 0 then
- begin
- rx:= rx div 2;ry:= ry div 2;
- end;
- if Land[yy + py, xx + px] <= lfAllObjMask then
- if gun then
- begin
- LandDirty[yy div 32, xx div 32]:= 1;
- if LandPixels[ry, rx] = 0 then
- Land[ly, lx]:= lfDamaged or lfObject
- else Land[ly, lx]:= lfDamaged or lfBasic
- end
- else Land[ly, lx]:= lf;
- if gun then
- LandPixels[ry, rx]:= (ExplosionBorderColor and (not AMask)) or (p^[px] and AMask)
- else LandPixels[ry, rx]:= addBgColor(LandPixels[ry, rx], p^[px]);
- end
- else allpx:= false
- end;
- p:= @(p^[s^.pitch shr 2])
- end;
-
- // Why is this here. For one thing, there's no test on +1 being safe.
- //Land[py, px+1]:= lfBasic;
-
- if allpx then
- UpdateLandTexture(xx, Pred(s^.h), yy, Pred(s^.w), true)
- else
- begin
- UpdateLandTexture(
- max(0, min(LAND_WIDTH, xx)),
- min(LAND_WIDTH - xx, Pred(s^.w)),
- max(0, min(LAND_WIDTH, yy)),
- min(LAND_HEIGHT - yy, Pred(s^.h)), false // could this be true without unnecessarily creating blanks?
- );
- end;
-////////////////////////////////// TODO - ASK UNC0RR FOR A GOOD HOME FOR THIS ////////////////////////////////////
- end
- end;
-
-if move then
- begin
- if gun then
- begin
- DeleteGear(Gear);
- exit
- end;
- Gear^.Pos:= 0;
- Gear^.X:= int2hwFloat(LongInt(GetRandom(snowRight - snowLeft)) + snowLeft);
- Gear^.Y:= int2hwFloat(LAND_HEIGHT + LongInt(GetRandom(50)) - 1325);
- Gear^.State:= Gear^.State or gstInvisible;
- end
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepGrave(Gear: PGear);
-begin
- if (Gear^.Message and gmDestroy) <> 0 then
- begin
- DeleteGear(Gear);
- exit
- end;
-
- AllInactive := false;
-
- if Gear^.dY.isNegative then
- if TestCollisionY(Gear, -1) then
- Gear^.dY := _0;
-
- if not Gear^.dY.isNegative then
- if TestCollisionY(Gear, 1) then
- begin
- Gear^.dY := - Gear^.dY * Gear^.Elasticity;
- if Gear^.dY > - _1div1024 then
- begin
- Gear^.Active := false;
- exit
- end
- else if Gear^.dY < - _0_03 then
- PlaySound(Gear^.ImpactSound)
- end;
-
- Gear^.Y := Gear^.Y + Gear^.dY;
- CheckGearDrowning(Gear);
- Gear^.dY := Gear^.dY + cGravity
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepBeeWork(Gear: PGear);
-var
- t: hwFloat;
- gX,gY,i: LongInt;
- uw, nuw: boolean;
- flower: PVisualGear;
-
-begin
- AllInactive := false;
- gX := hwRound(Gear^.X);
- gY := hwRound(Gear^.Y);
- uw := (Gear^.Tag <> 0); // was bee underwater last tick?
- nuw := (cWaterLine < gy + Gear^.Radius); // is bee underwater now?
-
- // if water entered or left
- if nuw <> uw then
- begin
- AddVisualGear(gX, cWaterLine, vgtSplash);
- AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet);
- AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet);
- AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet);
- AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet);
- StopSoundChan(Gear^.SoundChannel);
- if nuw then
- begin
- Gear^.SoundChannel := LoopSound(sndBeeWater);
- Gear^.Tag := 1;
- end
- else
- begin
- Gear^.SoundChannel := LoopSound(sndBee);
- Gear^.Tag := 0;
- end;
- end;
-
-
- if Gear^.Timer = 0 then
- Gear^.RenderTimer:= false
- else
- begin
- if (GameTicks and $F) = 0 then
- begin
- if (GameTicks and $30) = 0 then
- AddVisualGear(gX, gY, vgtBeeTrace);
- Gear^.dX := Gear^.Elasticity * (Gear^.dX + _0_000064 * (Gear^.Target.X - gX));
- Gear^.dY := Gear^.Elasticity * (Gear^.dY + _0_000064 * (Gear^.Target.Y - gY));
- // make sure new speed isn't higher than original one (which we stored in Friction variable)
- t := Gear^.Friction / Distance(Gear^.dX, Gear^.dY);
- Gear^.dX := Gear^.dX * t;
- Gear^.dY := Gear^.dY * t;
- end;
-
- Gear^.X := Gear^.X + Gear^.dX;
- Gear^.Y := Gear^.Y + Gear^.dY;
-
- end;
-
-
- CheckCollision(Gear);
- if ((Gear^.State and gstCollision) <> 0) then
- begin
- StopSoundChan(Gear^.SoundChannel);
- doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound);
- for i:= 0 to 31 do
- begin
- flower:= AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtStraightShot);
- if flower <> nil then
- with flower^ do
- begin
- Scale:= 0.75;
- dx:= 0.001 * (random(200));
- dy:= 0.001 * (random(200));
- if random(2) = 0 then
- dx := -dx;
- if random(2) = 0 then
- dy := -dy;
- FrameTicks:= random(250) + 250;
- State:= ord(sprTargetBee);
- end;
- end;
- DeleteGear(Gear);
- end;
-
- if (Gear^.Timer > 0) then
- dec(Gear^.Timer)
- else
- begin
- if nuw then
- begin
- StopSoundChan(Gear^.SoundChannel);
- CheckGearDrowning(Gear);
- end
- else
- doStepFallingGear(Gear);
- end;
-end;
-
-procedure doStepBee(Gear: PGear);
-begin
- AllInactive := false;
- Gear^.X := Gear^.X + Gear^.dX;
- Gear^.Y := Gear^.Y + Gear^.dY;
- Gear^.dY := Gear^.dY + cGravity;
- CheckCollision(Gear);
- if (Gear^.State and gstCollision) <> 0 then
- begin
- doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound);
- DeleteGear(Gear);
- exit
- end;
- dec(Gear^.Timer);
- if Gear^.Timer = 0 then
- begin
- Gear^.Hedgehog^.Gear^.Message:= Gear^.Hedgehog^.Gear^.Message and (not gmAttack);
- Gear^.Hedgehog^.Gear^.State:= Gear^.Hedgehog^.Gear^.State and (not gstAttacking);
- AttackBar:= 0;
-
- Gear^.SoundChannel := LoopSound(sndBee);
- Gear^.Timer := 5000;
- // save initial speed in otherwise unused Friction variable
- Gear^.Friction := Distance(Gear^.dX, Gear^.dY);
- Gear^.doStep := @doStepBeeWork
- end;
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepShotIdle(Gear: PGear);
-begin
- AllInactive := false;
- inc(Gear^.Timer);
- if Gear^.Timer > 75 then
- begin
- DeleteGear(Gear);
- AfterAttack
- end
-end;
-
-procedure doStepShotgunShot(Gear: PGear);
-var
- i: LongWord;
- shell: PVisualGear;
-begin
- AllInactive := false;
-
- if ((Gear^.State and gstAnimation) = 0) then
- begin
- dec(Gear^.Timer);
- if Gear^.Timer = 0 then
- begin
- PlaySound(sndShotgunFire);
- shell := AddVisualGear(hwRound(Gear^.x), hwRound(Gear^.y), vgtShell);
- if shell <> nil then
- begin
- shell^.dX := gear^.dX.QWordValue / -17179869184;
- shell^.dY := gear^.dY.QWordValue / -17179869184;
- shell^.Frame := 0
- end;
- Gear^.State := Gear^.State or gstAnimation
- end;
- exit
- end else
- if(Gear^.Hedgehog^.Gear = nil) or ((Gear^.Hedgehog^.Gear^.State and gstMoving) <> 0) then
- begin
- DeleteGear(Gear);
- AfterAttack;
- exit
- end
- else
- inc(Gear^.Timer);
-
- i := 200;
- repeat
- Gear^.X := Gear^.X + Gear^.dX;
- Gear^.Y := Gear^.Y + Gear^.dY;
- CheckCollision(Gear);
- if (Gear^.State and gstCollision) <> 0 then
- begin
- Gear^.X := Gear^.X + Gear^.dX * 8;
- Gear^.Y := Gear^.Y + Gear^.dY * 8;
- ShotgunShot(Gear);
- Gear^.doStep := @doStepShotIdle;
- exit
- end;
-
- CheckGearDrowning(Gear);
- if (Gear^.State and gstDrowning) <> 0 then
- begin
- Gear^.doStep := @doStepShotIdle;
- exit
- end;
- dec(i)
- until i = 0;
- if (hwRound(Gear^.X) and LAND_WIDTH_MASK <> 0) or (hwRound(Gear^.Y) and LAND_HEIGHT_MASK <> 0) then
- Gear^.doStep := @doStepShotIdle
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure spawnBulletTrail(Bullet: PGear);
-var oX, oY: hwFloat;
- VGear: PVisualGear;
-begin
- if Bullet^.PortalCounter = 0 then
- begin
- ox:= CurrentHedgehog^.Gear^.X + Int2hwFloat(GetLaunchX(CurrentHedgehog^.CurAmmoType, hwSign(CurrentHedgehog^.Gear^.dX), CurrentHedgehog^.Gear^.Angle));
- oy:= CurrentHedgehog^.Gear^.Y + Int2hwFloat(GetLaunchY(CurrentHedgehog^.CurAmmoType, CurrentHedgehog^.Gear^.Angle));
- end
- else
- begin
- ox:= Bullet^.Elasticity;
- oy:= Bullet^.Friction;
- end;
-
- // Bullet trail
- VGear := AddVisualGear(hwRound(ox), hwRound(oy), vgtLineTrail);
-
- if VGear <> nil then
- begin
- VGear^.X:= hwFloat2Float(ox);
- VGear^.Y:= hwFloat2Float(oy);
- VGear^.dX:= hwFloat2Float(Bullet^.X);
- VGear^.dY:= hwFloat2Float(Bullet^.Y);
-
- // reached edge of land. assume infinite beam. Extend it way out past camera
- if (hwRound(Bullet^.X) and LAND_WIDTH_MASK <> 0)
- or (hwRound(Bullet^.Y) and LAND_HEIGHT_MASK <> 0) then
- // only extend if not under water
- if hwRound(Bullet^.Y) < cWaterLine then
- begin
- VGear^.dX := VGear^.dX + max(LAND_WIDTH,4096) * (VGear^.dX - VGear^.X);
- VGear^.dY := VGear^.dY + max(LAND_WIDTH,4096) * (VGear^.dY - VGear^.Y);
- end;
-
- VGear^.Timer := 200;
- end;
-end;
-
-procedure doStepBulletWork(Gear: PGear);
-var
- i, x, y: LongWord;
- oX, oY: hwFloat;
- VGear: PVisualGear;
-begin
- AllInactive := false;
- inc(Gear^.Timer);
- i := 80;
- oX := Gear^.X;
- oY := Gear^.Y;
- repeat
- Gear^.X := Gear^.X + Gear^.dX;
- Gear^.Y := Gear^.Y + Gear^.dY;
- x := hwRound(Gear^.X);
- y := hwRound(Gear^.Y);
-
- if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) and (Land[y, x] <> 0) then
- inc(Gear^.Damage);
- // let's interrupt before a collision to give portals a chance to catch the bullet
- if (Gear^.Damage = 1) and (Gear^.Tag = 0) and not(CheckLandValue(x, y, lfLandMask)) then
- begin
- Gear^.Tag := 1;
- Gear^.Damage := 0;
- Gear^.X := Gear^.X - Gear^.dX;
- Gear^.Y := Gear^.Y - Gear^.dY;
- CheckGearDrowning(Gear);
- break;
- end
- else
- Gear^.Tag := 0;
-
- if Gear^.Damage > 5 then
- if Gear^.AmmoType = amDEagle then
- AmmoShove(Gear, 7, 20)
- else
- AmmoShove(Gear, Gear^.Timer, 20);
- CheckGearDrowning(Gear);
- dec(i)
- until (i = 0) or (Gear^.Damage > Gear^.Health) or ((Gear^.State and gstDrowning) <> 0);
-
- if Gear^.Damage > 0 then
- begin
- DrawTunnel(oX, oY, Gear^.dX, Gear^.dY, 82 - i, 1);
- dec(Gear^.Health, Gear^.Damage);
- Gear^.Damage := 0
- end;
- if ((Gear^.State and gstDrowning) <> 0) and (Gear^.Damage < Gear^.Health) and ((not SuddenDeathDmg and (WaterOpacity < $FF)) or (SuddenDeathDmg and (SDWaterOpacity < $FF))) then
- begin
- for i:=(Gear^.Health - Gear^.Damage) * 4 downto 0 do
- begin
- if Random(6) = 0 then
- AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtBubble);
- Gear^.X := Gear^.X + Gear^.dX;
- Gear^.Y := Gear^.Y + Gear^.dY;
- end;
- end;
-
- if (Gear^.Health <= 0)
- or (hwRound(Gear^.X) and LAND_WIDTH_MASK <> 0)
- or (hwRound(Gear^.Y) and LAND_HEIGHT_MASK <> 0) then
- begin
- if (Gear^.Kind = gtSniperRifleShot) and ((GameFlags and gfLaserSight) = 0) then
- cLaserSighting := false;
- if (Ammoz[Gear^.AmmoType].Ammo.NumPerTurn <= CurrentHedgehog^.MultiShootAttacks) and ((GameFlags and gfArtillery) = 0) then
- cArtillery := false;
-
- // Bullet Hit
- if (hwRound(Gear^.X) and LAND_WIDTH_MASK = 0) and (hwRound(Gear^.Y) and LAND_HEIGHT_MASK = 0) then
- begin
- VGear := AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtBulletHit);
- if VGear <> nil then
- begin
- VGear^.Angle := DxDy2Angle(-Gear^.dX, Gear^.dY);
- end;
- end;
-
- spawnBulletTrail(Gear);
- Gear^.doStep := @doStepShotIdle
- end;
-end;
-
-procedure doStepDEagleShot(Gear: PGear);
-begin
- PlaySound(sndGun);
- // add 3 initial steps to avoid problem with ammoshove related to calculation of radius + 1 radius as gear widths, and also just plain old weird angles
- Gear^.X := Gear^.X + Gear^.dX * 3;
- Gear^.Y := Gear^.Y + Gear^.dY * 3;
- Gear^.doStep := @doStepBulletWork
-end;
-
-procedure doStepSniperRifleShot(Gear: PGear);
-var
- HHGear: PGear;
- shell: PVisualGear;
-begin
- cArtillery := true;
- HHGear := Gear^.Hedgehog^.Gear;
- HHGear^.State := HHGear^.State or gstNotKickable;
- HedgehogChAngle(HHGear);
- if not cLaserSighting then
- // game does not have default laser sight. turn it on and give them a chance to aim
- begin
- cLaserSighting := true;
- HHGear^.Message := 0;
- if (HHGear^.Angle >= 32) then
- dec(HHGear^.Angle,32)
- end;
-
- if (HHGear^.Message and gmAttack) <> 0 then
- begin
- shell := AddVisualGear(hwRound(Gear^.x), hwRound(Gear^.y), vgtShell);
- if shell <> nil then
- begin
- shell^.dX := gear^.dX.QWordValue / -8589934592;
- shell^.dY := gear^.dY.QWordValue / -8589934592;
- shell^.Frame := 1
- end;
- Gear^.State := Gear^.State or gstAnimation;
- Gear^.dX := SignAs(AngleSin(HHGear^.Angle), HHGear^.dX) * _0_5;
- Gear^.dY := -AngleCos(HHGear^.Angle) * _0_5;
- PlaySound(sndGun);
- // add 3 initial steps to avoid problem with ammoshove related to calculation of radius + 1 radius as gear widths, and also just weird angles
- Gear^.X := Gear^.X + Gear^.dX * 3;
- Gear^.Y := Gear^.Y + Gear^.dY * 3;
- Gear^.doStep := @doStepBulletWork;
- end
- else
- if (GameTicks mod 32) = 0 then
- if (GameTicks mod 4096) < 2048 then
- begin
- if (HHGear^.Angle + 1 <= cMaxAngle) then
- inc(HHGear^.Angle)
- end
- else
- if (HHGear^.Angle >= 1) then
- dec(HHGear^.Angle);
-
- if (TurnTimeLeft > 0) then
- dec(TurnTimeLeft)
- else
- begin
- DeleteGear(Gear);
- AfterAttack
- end;
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepActionTimer(Gear: PGear);
-begin
-dec(Gear^.Timer);
-case Gear^.Kind of
- gtATStartGame:
- begin
- AllInactive := false;
- if Gear^.Timer = 0 then
- begin
- AddCaption(trmsg[sidStartFight], cWhiteColor, capgrpGameState);
- end
- end;
- gtATFinishGame:
- begin
- AllInactive := false;
- if Gear^.Timer = 1000 then
- begin
- ScreenFade := sfToBlack;
- ScreenFadeValue := 0;
- ScreenFadeSpeed := 1;
- end;
- if Gear^.Timer = 0 then
- begin
- SendIPC(_S'N');
- SendIPC(_S'q');
- GameState := gsExit
- end
- end;
- end;
-if Gear^.Timer = 0 then
- DeleteGear(Gear)
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepPickHammerWork(Gear: PGear);
-var
- i, ei, x, y: LongInt;
- HHGear: PGear;
-begin
- AllInactive := false;
- HHGear := Gear^.Hedgehog^.Gear;
- dec(Gear^.Timer);
- if ((GameFlags and gfInfAttack) <> 0) and (TurnTimeLeft > 0) then
- dec(TurnTimeLeft);
- if (TurnTimeLeft = 0) or (Gear^.Timer = 0)
- or((Gear^.Message and gmDestroy) <> 0)
- or((HHGear^.State and gstHHDriven) =0) then
- begin
- StopSoundChan(Gear^.SoundChannel);
- DeleteGear(Gear);
- AfterAttack;
- doStepHedgehogMoving(HHGear); // for gfInfAttack
- exit
- end;
-
- x:= hwRound(Gear^.X);
- y:= hwRound(Gear^.Y);
- if (Gear^.Timer mod 33) = 0 then
- begin
- HHGear^.State := HHGear^.State or gstNoDamage;
- doMakeExplosion(x, y + 7, 6, Gear^.Hedgehog, EXPLDontDraw);
- HHGear^.State := HHGear^.State and (not gstNoDamage)
- end;
-
- if (Gear^.Timer mod 47) = 0 then
- begin
- // ok. this was an attempt to turn off dust if not actually drilling land. I have no idea why it isn't working as expected
- if (( (y + 12) and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) and (Land[y + 12, x] > 255) then
- for i:= 0 to 1 do
- AddVisualGear(x - 5 + Random(10), y + 12, vgtDust);
-
- i := x - Gear^.Radius - LongInt(GetRandom(2));
- ei := x + Gear^.Radius + LongInt(GetRandom(2));
- while i <= ei do
- begin
- DrawExplosion(i, y + 3, 3);
- inc(i, 1)
- end;
-
- if CheckLandValue(hwRound(Gear^.X + Gear^.dX + SignAs(_6,Gear^.dX)), hwRound(Gear^.Y + _1_9), lfIndestructible) then
- begin
- Gear^.X := Gear^.X + Gear^.dX;
- Gear^.Y := Gear^.Y + _1_9;
- end;
- SetAllHHToActive;
- end;
- if TestCollisionYwithGear(Gear, 1) <> 0 then
- begin
- Gear^.dY := _0;
- SetLittle(HHGear^.dX);
- HHGear^.dY := _0;
- end
- else
- begin
- if CheckLandValue(hwRound(Gear^.X), hwRound(Gear^.Y + Gear^.dY + cGravity), lfLandMask) then
- begin
- Gear^.dY := Gear^.dY + cGravity;
- Gear^.Y := Gear^.Y + Gear^.dY
- end;
- if hwRound(Gear^.Y) > cWaterLine then
- Gear^.Timer := 1
- end;
-
- Gear^.X := Gear^.X + HHGear^.dX;
- if CheckLandValue(hwRound(Gear^.X), hwRound(Gear^.Y)-cHHRadius, lfLandMask) then
- begin
- HHGear^.X := Gear^.X;
- HHGear^.Y := Gear^.Y - int2hwFloat(cHHRadius)
- end;
-
- if (Gear^.Message and gmAttack) <> 0 then
- if (Gear^.State and gsttmpFlag) <> 0 then
- Gear^.Timer := 1
- else //there would be a mistake.
- else
- if (Gear^.State and gsttmpFlag) = 0 then
- Gear^.State := Gear^.State or gsttmpFlag;
- if ((Gear^.Message and gmLeft) <> 0) then
- Gear^.dX := - _0_3
- else
- if ((Gear^.Message and gmRight) <> 0) then
- Gear^.dX := _0_3
- else Gear^.dX := _0;
-end;
-
-procedure doStepPickHammer(Gear: PGear);
-var
- i, y: LongInt;
- ar: TRangeArray;
- HHGear: PGear;
-begin
- i := 0;
- HHGear := Gear^.Hedgehog^.Gear;
-
- y := hwRound(Gear^.Y) - cHHRadius * 2;
- while y < hwRound(Gear^.Y) do
- begin
- ar[i].Left := hwRound(Gear^.X) - Gear^.Radius - LongInt(GetRandom(2));
- ar[i].Right := hwRound(Gear^.X) + Gear^.Radius + LongInt(GetRandom(2));
- inc(y, 2);
- inc(i)
- end;
-
- DrawHLinesExplosions(@ar, 3, hwRound(Gear^.Y) - cHHRadius * 2, 2, Pred(i));
- Gear^.dY := HHGear^.dY;
- DeleteCI(HHGear);
-
- Gear^.SoundChannel := LoopSound(sndPickhammer);
- doStepPickHammerWork(Gear);
- Gear^.doStep := @doStepPickHammerWork
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-var
- BTPrevAngle, BTSteps: LongInt;
-
-procedure doStepBlowTorchWork(Gear: PGear);
-var
- HHGear: PGear;
- b: boolean;
- prevX: LongInt;
-begin
- AllInactive := false;
- dec(Gear^.Timer);
- if ((GameFlags and gfInfAttack) <> 0) and (TurnTimeLeft > 0) then
- dec(TurnTimeLeft);
-
- HHGear := Gear^.Hedgehog^.Gear;
-
- HedgehogChAngle(HHGear);
-
- b := false;
-
- if abs(LongInt(HHGear^.Angle) - BTPrevAngle) > 7 then
- begin
- Gear^.dX := SignAs(AngleSin(HHGear^.Angle) * _0_5, Gear^.dX);
- Gear^.dY := AngleCos(HHGear^.Angle) * ( - _0_5);
- BTPrevAngle := HHGear^.Angle;
- b := true
- end;
-
- if ((HHGear^.State and gstMoving) <> 0) then
- begin
- doStepHedgehogMoving(HHGear);
- if (HHGear^.State and gstHHDriven) = 0 then
- Gear^.Timer := 0
- end;
-
- if Gear^.Timer mod cHHStepTicks = 0 then
- begin
- b := true;
- if Gear^.dX.isNegative then
- HHGear^.Message := (HHGear^.Message and (gmAttack or gmUp or gmDown)) or gmLeft
- else
- HHGear^.Message := (HHGear^.Message and (gmAttack or gmUp or gmDown)) or gmRight;
-
- if ((HHGear^.State and gstMoving) = 0) then
- begin
- HHGear^.State := HHGear^.State and (not gstAttacking);
- prevX := hwRound(HHGear^.X);
-
- // why the call to HedgehogStep then a further increment of X?
- if (prevX = hwRound(HHGear^.X)) and
- CheckLandValue(hwRound(HHGear^.X + SignAs(_6, HHGear^.dX)), hwRound(HHGear^.Y),
- lfIndestructible) then HedgehogStep(HHGear);
-
- if (prevX = hwRound(HHGear^.X)) and
- CheckLandValue(hwRound(HHGear^.X + SignAs(_6, HHGear^.dX)), hwRound(HHGear^.Y),
- lfIndestructible) then HHGear^.X := HHGear^.X + SignAs(_1, HHGear^.dX);
- HHGear^.State := HHGear^.State or gstAttacking
- end;
-
- inc(BTSteps);
- if BTSteps = 7 then
- begin
- BTSteps := 0;
- if CheckLandValue(hwRound(HHGear^.X + Gear^.dX * (cHHRadius + cBlowTorchC) + SignAs(_6,Gear^.dX)), hwRound(HHGear^.Y + Gear^.dY * (cHHRadius + cBlowTorchC)),lfIndestructible) then
- begin
- Gear^.X := HHGear^.X + Gear^.dX * (cHHRadius + cBlowTorchC);
- Gear^.Y := HHGear^.Y + Gear^.dY * (cHHRadius + cBlowTorchC);
- end;
- HHGear^.State := HHGear^.State or gstNoDamage;
- AmmoShove(Gear, 2, 15);
- HHGear^.State := HHGear^.State and (not gstNoDamage)
- end;
- end;
-
- if b then
- begin
- DrawTunnel(HHGear^.X + Gear^.dX * cHHRadius,
- HHGear^.Y + Gear^.dY * cHHRadius - _1 -
- ((hwAbs(Gear^.dX) / (hwAbs(Gear^.dX) + hwAbs(Gear^.dY))) * _0_5 * 7),
- Gear^.dX, Gear^.dY,
- cHHStepTicks, cHHRadius * 2 + 7);
- end;
-
- if (TurnTimeLeft = 0) or (Gear^.Timer = 0)
- or ((HHGear^.Message and gmAttack) <> 0) then
- begin
- HHGear^.Message := 0;
- HHGear^.State := HHGear^.State and (not gstNotKickable);
- DeleteGear(Gear);
- AfterAttack
- end
-end;
-
-procedure doStepBlowTorch(Gear: PGear);
-var
- HHGear: PGear;
-begin
- BTPrevAngle := High(LongInt);
- BTSteps := 0;
- HHGear := Gear^.Hedgehog^.Gear;
- HedgehogChAngle(HHGear);
- Gear^.dX := SignAs(AngleSin(HHGear^.Angle) * _0_5, Gear^.dX);
- Gear^.dY := AngleCos(HHGear^.Angle) * ( - _0_5);
- DrawTunnel(HHGear^.X,
- HHGear^.Y + Gear^.dY * cHHRadius - _1 -
- ((hwAbs(Gear^.dX) / (hwAbs(Gear^.dX) + hwAbs(Gear^.dY))) * _0_5 * 7),
- Gear^.dX, Gear^.dY,
- cHHStepTicks, cHHRadius * 2 + 7);
- HHGear^.Message := 0;
- HHGear^.State := HHGear^.State or gstNotKickable;
- Gear^.doStep := @doStepBlowTorchWork
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepMine(Gear: PGear);
-var vg: PVisualGear;
- dxdy: hwFloat;
-begin
- if Gear^.Health = 0 then dxdy:= hwAbs(Gear^.dX)+hwAbs(Gear^.dY);
- if (Gear^.State and gstMoving) <> 0 then
- begin
- DeleteCI(Gear);
- doStepFallingGear(Gear);
- if (Gear^.State and gstMoving) = 0 then
- begin
- AddGearCI(Gear);
- Gear^.dX := _0;
- Gear^.dY := _0
- end;
- CalcRotationDirAngle(Gear);
- AllInactive := false
- end
- else if (GameTicks and $3F) = 25 then
- doStepFallingGear(Gear);
- if (Gear^.Health = 0) then
- begin
- if (dxdy > _0_4) and (Gear^.State and gstCollision <> 0) then
- inc(Gear^.Damage, hwRound(dxdy * _50));
-
- if ((GameTicks and $FF) = 0) and (Gear^.Damage > random(30)) then
- begin
- vg:= AddVisualGear(hwRound(Gear^.X) - 4 + Random(8), hwRound(Gear^.Y) - 4 - Random(4), vgtSmoke);
- if vg <> nil then
- vg^.Scale:= 0.5
- end;
-
- if (Gear^.Damage > 35) then
- begin
- doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound);
- DeleteGear(Gear);
- exit
- end
- end;
-
- if ((Gear^.State and gsttmpFlag) <> 0) and (Gear^.Health <> 0) then
- if ((Gear^.State and gstAttacking) = 0) then
- begin
- if ((GameTicks and $1F) = 0) then
- if CheckGearNear(Gear, gtHedgehog, 46, 32) <> nil then
- Gear^.State := Gear^.State or gstAttacking
- end
- else // gstAttacking <> 0
- begin
- AllInactive := false;
- if (Gear^.Timer and $FF) = 0 then
- PlaySound(sndMineTick);
- if Gear^.Timer = 0 then
- begin
- if ((Gear^.State and gstWait) <> 0)
- or (cMineDudPercent = 0)
- or (getRandom(100) > cMineDudPercent) then
- begin
- doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound);
- DeleteGear(Gear)
- end
- else
- begin
- vg:= AddVisualGear(hwRound(Gear^.X) - 4 + Random(8), hwRound(Gear^.Y) - 4 - Random(4), vgtSmoke);
- if vg <> nil then
- vg^.Scale:= 0.5;
- PlaySound(sndVaporize);
- Gear^.Health := 0;
- Gear^.Damage := 0;
- Gear^.State := Gear^.State and (not gstAttacking)
- end;
- exit
- end;
- dec(Gear^.Timer);
- end
- else // gsttmpFlag = 0
- if (TurnTimeLeft = 0)
- or ((GameFlags and gfInfAttack <> 0) and (GameTicks > Gear^.FlightTime))
- or (Gear^.Hedgehog^.Gear = nil) then
- Gear^.State := Gear^.State or gsttmpFlag;
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepSMine(Gear: PGear);
-begin
- // TODO: do real calculation?
- if TestCollisionXwithGear(Gear, 2)
- or (TestCollisionYwithGear(Gear, -2) <> 0)
- or TestCollisionXwithGear(Gear, -2)
- or (TestCollisionYwithGear(Gear, 2) <> 0) then
- begin
- if (not isZero(Gear^.dX)) or (not isZero(Gear^.dY)) then
- begin
- PlaySound(sndRopeAttach);
- Gear^.dX:= _0;
- Gear^.dY:= _0;
- AddGearCI(Gear);
- end;
- end
- else
- begin
- DeleteCI(Gear);
- doStepFallingGear(Gear);
- AllInactive := false;
- CalcRotationDirAngle(Gear);
- end;
-
- if ((Gear^.State and gsttmpFlag) <> 0) and (Gear^.Health <> 0) then
- begin
- if ((Gear^.State and gstAttacking) = 0) then
- begin
- if ((GameTicks and $1F) = 0) then
- if CheckGearNear(Gear, gtHedgehog, 46, 32) <> nil then
- Gear^.State := Gear^.State or gstAttacking
- end
- else // gstAttacking <> 0
- begin
- AllInactive := false;
- if Gear^.Timer = 0 then
- begin
- doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, Gear^.Hedgehog, EXPLAutoSound);
- DeleteGear(Gear);
- exit
- end else
- if (Gear^.Timer and $FF) = 0 then
- PlaySound(sndMineTick);
-
- dec(Gear^.Timer);
- end
- end
- else // gsttmpFlag = 0
- if (TurnTimeLeft = 0)
- or ((GameFlags and gfInfAttack <> 0) and (GameTicks > Gear^.FlightTime))
- or (Gear^.Hedgehog^.Gear = nil) then
- Gear^.State := Gear^.State or gsttmpFlag;
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepDynamite(Gear: PGear);
-begin
- doStepFallingGear(Gear);
- AllInactive := false;
- if Gear^.Timer mod 166 = 0 then
- inc(Gear^.Tag);
- if Gear^.Timer = 1000 then // might need better timing
- makeHogsWorry(Gear^.X, Gear^.Y, 75);
- if Gear^.Timer = 0 then
- begin
- doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 75, Gear^.Hedgehog, EXPLAutoSound);
- DeleteGear(Gear);
- exit
- end;
- dec(Gear^.Timer);
-end;
-
-///////////////////////////////////////////////////////////////////////////////
-
-procedure doStepRollingBarrel(Gear: PGear);
-var
- i: LongInt;
- particle: PVisualGear;
- dxdy: hwFloat;
-begin
- if (Gear^.dY.QWordValue = 0) and (Gear^.dY.QWordValue = 0) and (TestCollisionYwithGear(Gear, 1) = 0) then
- SetLittle(Gear^.dY);
- Gear^.State := Gear^.State or gstAnimation;
- if Gear^.Health < cBarrelHealth then Gear^.State:= Gear^.State and not gstFrozen;
-
- if ((Gear^.dX.QWordValue <> 0)
- or (Gear^.dY.QWordValue <> 0)) then
- begin
- DeleteCI(Gear);
- AllInactive := false;
- dxdy:= hwAbs(Gear^.dX)+hwAbs(Gear^.dY);
- doStepFallingGear(Gear);
- if (Gear^.State and gstCollision <> 0) and(dxdy > _0_4) then
- begin
- if (TestCollisionYwithGear(Gear, 1) <> 0) then
- begin
- Gear^.State := Gear^.State or gsttmpFlag;
- for i:= min(12, hwRound(dxdy*_10)) downto 0 do
- begin
- particle := AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12,vgtDust);
- if particle <> nil then
- particle^.dX := particle^.dX + (Gear^.dX.QWordValue / 21474836480)
- end
- end;
- inc(Gear^.Damage, hwRound(dxdy * _50))
- end;
- CalcRotationDirAngle(Gear);
- //CheckGearDrowning(Gear)
- end
- else
- begin
- Gear^.State := Gear^.State or gsttmpFlag;
- AddGearCI(Gear)
- end;
-
-(*
-Attempt to make a barrel knock itself over an edge. Would need more checks to avoid issues like burn damage
- begin
- x:= hwRound(Gear^.X);
- y:= hwRound(Gear^.Y);
- if (((y+1) and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) then
- if (Land[y+1, x] = 0) then
- begin
- if (((y+1) and LAND_HEIGHT_MASK) = 0) and (((x+Gear^.Radius-2) and LAND_WIDTH_MASK) = 0) and (Land[y+1, x+Gear^.Radius-2] = 0) then
- Gear^.dX:= -_0_08
- else if (((y+1 and LAND_HEIGHT_MASK)) = 0) and (((x-(Gear^.Radius-2)) and LAND_WIDTH_MASK) = 0) and (Land[y+1, x-(Gear^.Radius-2)] = 0) then
- Gear^.dX:= _0_08;
- end;
- if Gear^.dX.QWordValue = 0 then AddGearCI(Gear)
- end; *)
-
- if not Gear^.dY.isNegative and (Gear^.dY < _0_001) and (TestCollisionYwithGear(Gear, 1) <> 0) then
- Gear^.dY := _0;
- if hwAbs(Gear^.dX) < _0_001 then
- Gear^.dX := _0;
-
- if (Gear^.Health > 0) and ((Gear^.Health * 100 div cBarrelHealth) < random(90)) and ((GameTicks and $FF) = 0) then
- if (cBarrelHealth div Gear^.Health) > 2 then
- AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmoke)
- else
- AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmokeWhite);
- dec(Gear^.Health, Gear^.Damage);
- Gear^.Damage := 0;
- if Gear^.Health <= 0 then
- doStepCase(Gear);
-end;
-
-procedure doStepCase(Gear: PGear);
-var
- i, x, y: LongInt;
- k: TGearType;
- dX, dY: HWFloat;
- hog: PHedgehog;
- sparkles: PVisualGear;
- gi: PGear;
-begin
- k := Gear^.Kind;
-
- if (Gear^.Message and gmDestroy) > 0 then
- begin
- DeleteGear(Gear);
- FreeActionsList;
- SetAllToActive;
- // something (hh, mine, etc...) could be on top of the case
- with CurrentHedgehog^ do
- if Gear <> nil then
- Gear^.Message := Gear^.Message and (not (gmLJump or gmHJump));
- exit
- end;
- if (k = gtExplosives) and (Gear^.Health < cBarrelHealth) then Gear^.State:= Gear^.State and not gstFrozen;
-
- if ((k <> gtExplosives) and (Gear^.Damage > 0)) or ((k = gtExplosives) and (Gear^.Health<=0)) then
- begin
- x := hwRound(Gear^.X);
- y := hwRound(Gear^.Y);
- hog:= Gear^.Hedgehog;
-
- DeleteGear(Gear);
- // <-- delete gear!
-
- if k = gtCase then
- begin
- doMakeExplosion(x, y, 25, hog, EXPLAutoSound);
- for i:= 0 to 63 do
- AddGear(x, y, gtFlame, 0, _0, _0, 0);
- end
- else if k = gtExplosives then
- begin
- doMakeExplosion(x, y, 75, hog, EXPLAutoSound);
- for i:= 0 to 31 do
- begin
- dX := AngleCos(i * 64) * _0_5 * (getrandomf + _1);
- dY := AngleSin(i * 64) * _0_5 * (getrandomf + _1);
- AddGear(x, y, gtFlame, 0, dX, dY, 0);
- AddGear(x, y, gtFlame, gstTmpFlag, -dX, -dY, 0);
- end
- end;
- exit
- end;
-
- if k = gtExplosives then
- begin
- //if V > _0_03 then Gear^.State:= Gear^.State or gstAnimation;
- if (hwAbs(Gear^.dX) > _0_15) or ((hwAbs(Gear^.dY) > _0_15) and (hwAbs(Gear^.dX) > _0_02)) then
- begin
- Gear^.doStep := @doStepRollingBarrel;
- exit;
- end
- else Gear^.dX:= _0;
-
- if ((Gear^.Health * 100 div cBarrelHealth) < random(90)) and ((GameTicks and $FF) = 0) then
- if (cBarrelHealth div Gear^.Health) > 2 then
- AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmoke)
- else
- AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmokeWhite);
- dec(Gear^.Health, Gear^.Damage);
- Gear^.Damage := 0;
- end
- else
- begin
- if (Gear^.Pos <> posCaseHealth) and (GameTicks and $1FFF = 0) then // stir 'em up periodically
- begin
- gi := GearsList;
- while gi <> nil do
- begin
- if gi^.Kind = gtGenericFaller then
- begin
- gi^.Active:= true;
- gi^.X:= int2hwFloat(GetRandom(rightX-leftX)+leftX);
- gi^.Y:= int2hwFloat(GetRandom(LAND_HEIGHT-topY)+topY);
- gi^.dX:= _90-(GetRandomf*_360);
- gi^.dY:= _90-(GetRandomf*_360)
- end;
- gi := gi^.NextGear
- end
- end;
-
- if Gear^.Timer = 500 then
- begin
-(* Can't make sparkles team coloured without working out what the next team is going to be. This should be solved, really, since it also screws up
- voices. Reinforcements voices is heard for active team, not team-to-be. Either that or change crate spawn from end of turn to start, although that
- has its own complexities. *)
- // Abuse a couple of gear values to track origin
- Gear^.Angle:= hwRound(Gear^.Y);
- Gear^.Tag:= random(2);
- inc(Gear^.Timer)
- end;
- if Gear^.Timer < 1833 then inc(Gear^.Timer);
- if Gear^.Timer = 1000 then
- begin
- sparkles:= AddVisualGear(hwRound(Gear^.X), Gear^.Angle, vgtDust, 1);
- if sparkles <> nil then
- begin
- sparkles^.dX:= 0;
- sparkles^.dY:= 0;
- sparkles^.Angle:= 270;
- if Gear^.Tag = 1 then
- sparkles^.Tint:= $3744D7FF
- else sparkles^.Tint:= $FAB22CFF
- end;
- end;
- if Gear^.Timer < 1000 then
- begin
- AllInactive:= false;
- exit
- end
- end;
-
-
- if (Gear^.dY.QWordValue <> 0)
- or (TestCollisionYwithGear(Gear, 1) = 0) then
- begin
- AllInactive := false;
-
- Gear^.dY := Gear^.dY + cGravity;
-
- if (Gear^.dY.isNegative) and (TestCollisionYwithGear(Gear, -1) <> 0) then
- Gear^.dY := _0;
-
- Gear^.Y := Gear^.Y + Gear^.dY;
-
- if (not Gear^.dY.isNegative) and (Gear^.dY > _0_001) then
- SetAllHHToActive(false);
-
- if (not Gear^.dY.isNegative) and (TestCollisionYwithGear(Gear, 1) <> 0) then
- begin
- if (Gear^.dY > _0_2) and (k = gtExplosives) then
- inc(Gear^.Damage, hwRound(Gear^.dY * _70));
-
- if Gear^.dY > _0_2 then
- for i:= min(12, hwRound(Gear^.dY*_10)) downto 0 do
- AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12, vgtDust);
-
- Gear^.dY := - Gear^.dY * Gear^.Elasticity;
- if Gear^.dY > - _0_001 then
- Gear^.dY := _0
- else if Gear^.dY < - _0_03 then
- PlaySound(Gear^.ImpactSound);
- end;
- //if Gear^.dY > - _0_001 then Gear^.dY:= _0
- CheckGearDrowning(Gear);
- end;
-
- if (Gear^.dY.QWordValue = 0) then
- AddGearCI(Gear)
- else if (Gear^.dY.QWordValue <> 0) then
- DeleteCI(Gear)
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-
-procedure doStepTarget(Gear: PGear);
-begin
- if (Gear^.Timer = 0) and (Gear^.Tag = 0) then
- PlaySound(sndWarp);
-
- if (Gear^.Tag = 0) and (Gear^.Timer < 1000) then
- inc(Gear^.Timer)
- else if Gear^.Tag = 1 then
- Gear^.Tag := 2
- else if Gear^.Tag = 2 then
- if Gear^.Timer > 0 then
- dec(Gear^.Timer)
- else
- begin
- DeleteGear(Gear);
- exit;
- end;
-
- doStepCase(Gear)
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepIdle(Gear: PGear);
-begin
- AllInactive := false;
- dec(Gear^.Timer);
- if Gear^.Timer = 0 then
- begin
- DeleteGear(Gear);
- AfterAttack
- end
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepShover(Gear: PGear);
-var
- HHGear: PGear;
-begin
- HHGear := Gear^.Hedgehog^.Gear;
- HHGear^.State := HHGear^.State or gstNoDamage;
- DeleteCI(HHGear);
-
- AmmoShove(Gear, 30, 115);
-
- HHGear^.State := (HHGear^.State and (not gstNoDamage)) or gstMoving;
- Gear^.Timer := 250;
- Gear^.doStep := @doStepIdle
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepWhip(Gear: PGear);
-var
- HHGear: PGear;
- i: LongInt;
-begin
- HHGear := Gear^.Hedgehog^.Gear;
- HHGear^.State := HHGear^.State or gstNoDamage;
- DeleteCI(HHGear);
-
- for i:= 0 to 3 do
- begin
- AmmoShove(Gear, 30, 25);
- Gear^.X := Gear^.X + Gear^.dX * 5
- end;
-
- HHGear^.State := (HHGear^.State and (not gstNoDamage)) or gstMoving;
-
- Gear^.Timer := 250;
- Gear^.doStep := @doStepIdle
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepFlame(Gear: PGear);
-var
- gX,gY,i: LongInt;
- sticky: Boolean;
- vgt: PVisualGear;
- tdX,tdY: HWFloat;
-begin
- sticky:= (Gear^.State and gsttmpFlag) <> 0;
- if not sticky then AllInactive := false;
-
- if TestCollisionYwithGear(Gear, 1) = 0 then
- begin
- AllInactive := false;
-
- if ((GameTicks mod 100) = 0) then
- begin
- vgt:= AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtFire, gstTmpFlag);
- if vgt <> nil then
- begin
- vgt^.dx:= 0;
- vgt^.dy:= 0;
- vgt^.FrameTicks:= 1800 div (Gear^.Tag mod 3 + 2);
- end;
- end;
-
-
- if Gear^.dX.QWordValue > _0_01.QWordValue then
- Gear^.dX := Gear^.dX * _0_995;
-
- Gear^.dY := Gear^.dY + cGravity;
- // if sticky then Gear^.dY := Gear^.dY + cGravity;
-
- if Gear^.dY.QWordValue > _0_2.QWordValue then
- Gear^.dY := Gear^.dY * _0_995;
-
- //if sticky then Gear^.X := Gear^.X + Gear^.dX else
- Gear^.X := Gear^.X + Gear^.dX + cWindSpeed * 640;
- Gear^.Y := Gear^.Y + Gear^.dY;
-
- if (hwRound(Gear^.Y) > cWaterLine) then
- begin
- gX := hwRound(Gear^.X);
- for i:= 0 to 3 do
- AddVisualGear(gX - 16 + Random(32), cWaterLine - 16 + Random(16), vgtSteam);
- PlaySound(sndVaporize);
- DeleteGear(Gear);
- exit
- end
- end
- else
- begin
- if sticky then
- begin
- Gear^.Radius := 7;
- tdX:= Gear^.dX;
- tdY:= Gear^.dY;
- Gear^.dX.QWordValue:= 214748365;
- Gear^.dY.QWordValue:= 429496730;
- Gear^.dX.isNegative:= getrandom(2)<>1;
- Gear^.dY.isNegative:= true;
- AmmoShove(Gear, 2, 125);
- Gear^.dX:= tdX;
- Gear^.dY:= tdY;
- Gear^.Radius := 1
- end;
- if Gear^.Timer > 0 then
- begin
- dec(Gear^.Timer);
- inc(Gear^.Damage)
- end
- else
- begin
- gX := hwRound(Gear^.X);
- gY := hwRound(Gear^.Y);
- // Standard fire
- if not sticky then
- begin
- if ((GameTicks and $1) = 0) then
- begin
- Gear^.Radius := 7;
- tdX:= Gear^.dX;
- tdY:= Gear^.dY;
- Gear^.dX.QWordValue:= 214748365;
- Gear^.dY.QWordValue:= 429496730;
- Gear^.dX.isNegative:= getrandom(2)<>1;
- Gear^.dY.isNegative:= true;
- AmmoShove(Gear, 6, 100);
- Gear^.dX:= tdX;
- Gear^.dY:= tdY;
- Gear^.Radius := 1;
- end
- else if ((GameTicks and $3) = 3) then
- doMakeExplosion(gX, gY, 8, Gear^.Hedgehog, 0);//, EXPLNoDamage);
- //DrawExplosion(gX, gY, 4);
-
- if ((GameTicks and $7) = 0) and (Random(2) = 0) then
- for i:= Random(2) downto 0 do
- AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke);
-
- if Gear^.Health > 0 then
- dec(Gear^.Health);
- Gear^.Timer := 450 - Gear^.Tag * 8
- end
- else
- begin
- // Modified fire
- if ((GameTicks and $7FF) = 0) and ((GameFlags and gfSolidLand) = 0) then
- begin
- DrawExplosion(gX, gY, 4);
-
- for i:= Random(3) downto 0 do
- AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke);
- end;
-
-// This one is interesting. I think I understand the purpose, but I wonder if a bit more fuzzy of kicking could be done with getrandom.
- Gear^.Timer := 100 - Gear^.Tag * 3;
- if (Gear^.Damage > 3000+Gear^.Tag*1500) then
- Gear^.Health := 0
- end
- end
- end;
- if Gear^.Health = 0 then
- begin
- gX := hwRound(Gear^.X);
- gY := hwRound(Gear^.Y);
- if not sticky then
- begin
- if ((GameTicks and $3) = 0) and (Random(1) = 0) then
- for i:= Random(2) downto 0 do
- AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke);
- end
- else
- for i:= Random(3) downto 0 do
- AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke);
-
- DeleteGear(Gear)
- end;
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepFirePunchWork(Gear: PGear);
-var
- HHGear: PGear;
-begin
- AllInactive := false;
- if ((Gear^.Message and gmDestroy) <> 0) then
- begin
- DeleteGear(Gear);
- AfterAttack;
- exit
- end;
-
- HHGear := Gear^.Hedgehog^.Gear;
- if hwRound(HHGear^.Y) <= Gear^.Tag - 2 then
- begin
- Gear^.Tag := hwRound(HHGear^.Y);
- DrawTunnel(HHGear^.X - int2hwFloat(cHHRadius), HHGear^.Y - _1, _0_5, _0, cHHRadius * 4, 2);
- HHGear^.State := HHGear^.State or gstNoDamage;
- Gear^.Y := HHGear^.Y;
- AmmoShove(Gear, 30, 40);
- HHGear^.State := HHGear^.State and (not gstNoDamage)
- end;
-
- HHGear^.dY := HHGear^.dY + cGravity;
- if not (HHGear^.dY.isNegative) then
- begin
- HHGear^.State := HHGear^.State or gstMoving;
- DeleteGear(Gear);
- AfterAttack;
- exit
- end;
-
- if CheckLandValue(hwRound(HHGear^.X), hwRound(HHGear^.Y + HHGear^.dY + SignAs(_6,Gear^.dY)),
- lfIndestructible) then
- HHGear^.Y := HHGear^.Y + HHGear^.dY
-end;
-
-procedure doStepFirePunch(Gear: PGear);
-var
- HHGear: PGear;
-begin
- AllInactive := false;
- HHGear := Gear^.Hedgehog^.Gear;
- DeleteCI(HHGear);
- //HHGear^.X := int2hwFloat(hwRound(HHGear^.X)) - _0_5; WTF?
- HHGear^.dX := SignAs(cLittle, Gear^.dX);
-
- HHGear^.dY := - _0_3;
-
- Gear^.X := HHGear^.X;
- Gear^.dX := SignAs(_0_45, Gear^.dX);
- Gear^.dY := - _0_9;
- Gear^.doStep := @doStepFirePunchWork;
- DrawTunnel(HHGear^.X - int2hwFloat(cHHRadius), HHGear^.Y + _1, _0_5, _0, cHHRadius * 4, 5);
-
- PlaySoundV(TSound(ord(sndFirePunch1) + GetRandom(6)), HHGear^.Hedgehog^.Team^.voicepack)
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-
-procedure doStepParachuteWork(Gear: PGear);
-var
- HHGear: PGear;
-begin
- HHGear := Gear^.Hedgehog^.Gear;
-
- inc(Gear^.Timer);
-
- if (TestCollisionYwithGear(HHGear, 1) <> 0)
- or ((HHGear^.State and gstHHDriven) = 0)
- or CheckGearDrowning(HHGear)
- or ((Gear^.Message and gmAttack) <> 0) then
- begin
- with HHGear^ do
- begin
- Message := 0;
- SetLittle(dX);
- dY := _0;
- State := State or gstMoving;
- end;
- DeleteGear(Gear);
- isCursorVisible := false;
- ApplyAmmoChanges(HHGear^.Hedgehog^);
- exit
- end;
-
- HHGear^.X := HHGear^.X + cWindSpeed * 200;
-
- if (Gear^.Message and gmLeft) <> 0 then
- HHGear^.X := HHGear^.X - cMaxWindSpeed * 80
-
- else if (Gear^.Message and gmRight) <> 0 then
- HHGear^.X := HHGear^.X + cMaxWindSpeed * 80;
-
- if (Gear^.Message and gmUp) <> 0 then
- HHGear^.Y := HHGear^.Y - cGravity * 40
-
- else if (Gear^.Message and gmDown) <> 0 then
- HHGear^.Y := HHGear^.Y + cGravity * 40;
-
- // don't drift into obstacles
- if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then
- HHGear^.X := HHGear^.X - int2hwFloat(hwSign(HHGear^.dX));
- HHGear^.Y := HHGear^.Y + cGravity * 100;
- Gear^.X := HHGear^.X;
- Gear^.Y := HHGear^.Y
-end;
-
-procedure doStepParachute(Gear: PGear);
-var
- HHGear: PGear;
-begin
- HHGear := Gear^.Hedgehog^.Gear;
-
- DeleteCI(HHGear);
-
- AfterAttack;
-
- HHGear^.State := HHGear^.State and (not (gstAttacking or gstAttacked or gstMoving));
- HHGear^.Message := HHGear^.Message and (not gmAttack);
-
- Gear^.doStep := @doStepParachuteWork;
-
- Gear^.Message := HHGear^.Message;
- doStepParachuteWork(Gear)
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepAirAttackWork(Gear: PGear);
-begin
- AllInactive := false;
- Gear^.X := Gear^.X + cAirPlaneSpeed * Gear^.Tag;
-
- if (Gear^.Health > 0)and(not (Gear^.X < Gear^.dX))and(Gear^.X < Gear^.dX + cAirPlaneSpeed) then
- begin
- dec(Gear^.Health);
- case Gear^.State of
- 0: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtAirBomb, 0, cBombsSpeed * Gear^.Tag, _0, 0);
- 1: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtMine, 0, cBombsSpeed * Gear^.Tag, _0, 0);
- 2: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtNapalmBomb, 0, cBombsSpeed * Gear^.Tag, _0, 0);
- 3: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtDrill, gsttmpFlag, cBombsSpeed * Gear^.Tag, _0, Gear^.Timer + 1);
- //4: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtWaterMelon, 0, cBombsSpeed *
- // Gear^.Tag, _0, 5000);
- end;
- Gear^.dX := Gear^.dX + int2hwFloat(30 * Gear^.Tag);
- StopSoundChan(Gear^.SoundChannel, 4000);
- end;
-
- if (GameTicks and $3F) = 0 then
- AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace);
-
- if (hwRound(Gear^.X) > (max(LAND_WIDTH,4096)+2048)) or (hwRound(Gear^.X) < -2048) then
- begin
- // avoid to play forever (is this necessary?)
- StopSoundChan(Gear^.SoundChannel);
- DeleteGear(Gear)
- end;
-end;
-
-procedure doStepAirAttack(Gear: PGear);
-begin
- AllInactive := false;
-
- if Gear^.X.QWordValue = 0 then
- begin
- Gear^.Tag := 1;
- Gear^.X := -_2048;
- end
- else
- begin
- Gear^.Tag := -1;
- Gear^.X := int2hwFloat(max(LAND_WIDTH,4096) + 2048);
- end;
-
- Gear^.Y := int2hwFloat(topY-300);
- Gear^.dX := int2hwFloat(Gear^.Target.X - 5 * Gear^.Tag * 15);
-
- // calcs for Napalm Strike, so that it will hit the target (without wind at least :P)
- if (Gear^.State = 2) then
- Gear^.dX := Gear^.dX - cBombsSpeed * Gear^.Tag * 900
- // calcs for regular falling gears
- else if (int2hwFloat(Gear^.Target.Y) - Gear^.Y > _0) then
- Gear^.dX := Gear^.dX - cBombsSpeed * hwSqrt((int2hwFloat(Gear^.Target.Y) - Gear^.Y) * 2 /
- cGravity) * Gear^.Tag;
-
- Gear^.Health := 6;
- Gear^.doStep := @doStepAirAttackWork;
- Gear^.SoundChannel := LoopSound(sndPlane, 4000);
-
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-
-procedure doStepAirBomb(Gear: PGear);
-begin
- AllInactive := false;
- doStepFallingGear(Gear);
- if (Gear^.State and gstCollision) <> 0 then
- begin
- doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, Gear^.Hedgehog, EXPLAutoSound);
- DeleteGear(Gear);
- with mobileRecord do
- if (performRumble <> nil) and (not fastUntilLag) then
- performRumble(kSystemSoundID_Vibrate);
- exit
- end;
- if (GameTicks and $3F) = 0 then
- AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace)
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-
-procedure doStepGirder(Gear: PGear);
-var
- HHGear: PGear;
- x, y, tx, ty: hwFloat;
-begin
- AllInactive := false;
-
- HHGear := Gear^.Hedgehog^.Gear;
- tx := int2hwFloat(Gear^.Target.X);
- ty := int2hwFloat(Gear^.Target.Y);
- x := HHGear^.X;
- y := HHGear^.Y;
-
- if (Distance(tx - x, ty - y) > _256)
- or (not TryPlaceOnLand(Gear^.Target.X - SpritesData[sprAmGirder].Width div 2, Gear^.Target.Y - SpritesData[sprAmGirder].Height div 2, sprAmGirder, Gear^.State, true, false)) then
- begin
- PlaySound(sndDenied);
- HHGear^.Message := HHGear^.Message and (not gmAttack);
- HHGear^.State := HHGear^.State and (not gstAttacking);
- HHGear^.State := HHGear^.State or gstHHChooseTarget;
- isCursorVisible := true;
- DeleteGear(Gear)
- end
- else
- begin
- PlaySound(sndPlaced);
- DeleteGear(Gear);
- AfterAttack;
- end;
-
- HHGear^.State := HHGear^.State and (not (gstAttacking or gstAttacked));
- HHGear^.Message := HHGear^.Message and (not gmAttack);
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepTeleportAfter(Gear: PGear);
-var
- HHGear: PGear;
-begin
- HHGear := Gear^.Hedgehog^.Gear;
- doStepHedgehogMoving(HHGear);
- // if not infattack mode wait for hedgehog finish falling to collect cases
- if ((GameFlags and gfInfAttack) <> 0)
- or ((HHGear^.State and gstMoving) = 0)
- or (Gear^.Hedgehog^.Gear^.Damage > 0)
- or ((HHGear^.State and gstDrowning) = 1) then
- begin
- DeleteGear(Gear);
- AfterAttack
- end
-end;
-
-procedure doStepTeleportAnim(Gear: PGear);
-begin
- if (Gear^.Hedgehog^.Gear^.Damage > 0) then
- begin
- DeleteGear(Gear);
- AfterAttack;
- end;
- inc(Gear^.Timer);
- if Gear^.Timer = 65 then
- begin
- Gear^.Timer := 0;
- inc(Gear^.Pos);
- if Gear^.Pos = 11 then
- Gear^.doStep := @doStepTeleportAfter
- end;
-end;
-
-procedure doStepTeleport(Gear: PGear);
-var
- HHGear: PGear;
-begin
- AllInactive := false;
-
- HHGear := Gear^.Hedgehog^.Gear;
- if not TryPlaceOnLand(Gear^.Target.X - SpritesData[sprHHTelepMask].Width div 2,
- Gear^.Target.Y - SpritesData[sprHHTelepMask].Height div 2,
- sprHHTelepMask, 0, false, false) then
- begin
- HHGear^.Message := HHGear^.Message and (not gmAttack);
- HHGear^.State := HHGear^.State and (not gstAttacking);
- HHGear^.State := HHGear^.State or gstHHChooseTarget;
- DeleteGear(Gear);
- isCursorVisible := true;
- PlaySound(sndDenied)
- end
- else
- begin
- DeleteCI(HHGear);
- SetAllHHToActive;
- Gear^.doStep := @doStepTeleportAnim;
-
- // copy old HH position and direction to Gear (because we need them for drawing the vanishing hog)
- Gear^.dX := HHGear^.dX;
- // retrieve the cursor direction (it was previously copied to X so it doesn't get lost)
- HHGear^.dX.isNegative := (Gear^.X.QWordValue <> 0);
- Gear^.X := HHGear^.X;
- Gear^.Y := HHGear^.Y;
- HHGear^.X := int2hwFloat(Gear^.Target.X);
- HHGear^.Y := int2hwFloat(Gear^.Target.Y);
- HHGear^.State := HHGear^.State or gstMoving;
- Gear^.Hedgehog^.Unplaced := false;
- isCursorVisible := false;
- playSound(sndWarp)
- end;
- Gear^.Target.X:= NoPointX
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepSwitcherWork(Gear: PGear);
-var
- HHGear: PGear;
- hedgehog: PHedgehog;
- State: Longword;
-begin
- AllInactive := false;
-
- if ((Gear^.Message and (not gmSwitch)) <> 0) or (TurnTimeLeft = 0) then
- begin
- hedgehog := Gear^.Hedgehog;
- //Msg := Gear^.Message and (not gmSwitch);
- DeleteGear(Gear);
- ApplyAmmoChanges(hedgehog^);
-
- HHGear := CurrentHedgehog^.Gear;
- ApplyAmmoChanges(HHGear^.Hedgehog^);
- //HHGear^.Message := Msg;
- exit
- end;
-
- if (Gear^.Message and gmSwitch) <> 0 then
- begin
- HHGear := CurrentHedgehog^.Gear;
- HHGear^.Message := HHGear^.Message and (not gmSwitch);
- Gear^.Message := Gear^.Message and (not gmSwitch);
- State := HHGear^.State;
- HHGear^.State := 0;
- HHGear^.Z := cHHZ;
- HHGear^.Active := false;
- HHGear^.Message:= HHGear^.Message or gmRemoveFromList or gmAddToList;
-
- PlaySound(sndSwitchHog);
-
- repeat
- CurrentTeam^.CurrHedgehog := Succ(CurrentTeam^.CurrHedgehog) mod (CurrentTeam^.HedgehogsNumber);
- until (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil) and
- (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear^.Damage = 0) and
- (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Effects[heFrozen]=0);
-
- SwitchCurrentHedgehog(@CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog]);
- AmmoMenuInvalidated:= true;
-
- HHGear := CurrentHedgehog^.Gear;
- HHGear^.State := State;
- HHGear^.Active := true;
- FollowGear := HHGear;
- HHGear^.Z := cCurrHHZ;
- HHGear^.Message:= HHGear^.Message or gmRemoveFromList or gmAddToList;
- Gear^.X := HHGear^.X;
- Gear^.Y := HHGear^.Y
- end;
-end;
-
-procedure doStepSwitcher(Gear: PGear);
-var
- HHGear: PGear;
-begin
- Gear^.doStep := @doStepSwitcherWork;
-
- HHGear := Gear^.Hedgehog^.Gear;
- OnUsedAmmo(HHGear^.Hedgehog^);
- with HHGear^ do
- begin
- State := State and (not gstAttacking);
- Message := Message and (not gmAttack)
- end
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepMortar(Gear: PGear);
-var
- dX, dY, gdX, gdY: hwFloat;
- i: LongInt;
-begin
- AllInactive := false;
- gdX := Gear^.dX;
- gdY := Gear^.dY;
-
- doStepFallingGear(Gear);
- if (Gear^.State and gstCollision) <> 0 then
- begin
- doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 20, Gear^.Hedgehog, EXPLAutoSound);
- gdX.isNegative := not gdX.isNegative;
- gdY.isNegative := not gdY.isNegative;
- gdX:= gdX*_0_2;
- gdY:= gdY*_0_2;
-
- for i:= 0 to 4 do
- begin
- dX := gdX + rndSign(GetRandomf) * _0_03;
- dY := gdY + rndSign(GetRandomf) * _0_03;
- AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtCluster, 0, dX, dY, 25);
- end;
-
- DeleteGear(Gear);
- exit
- end;
-
- if (GameTicks and $3F) = 0 then
- begin
- if hwRound(Gear^.Y) > cWaterLine then
- AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtBubble)
- else AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace)
- end
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepKamikazeWork(Gear: PGear);
-var
- i: LongWord;
- HHGear: PGear;
- sparkles: PVisualGear;
- hasWishes: boolean;
-begin
- AllInactive := false;
- hasWishes:= ((Gear^.Message and (gmPrecise or gmSwitch)) = (gmPrecise or gmSwitch));
- if hasWishes then
- Gear^.AdvBounce:= 1;
-
- HHGear := Gear^.Hedgehog^.Gear;
- if HHGear = nil then
- begin
- DeleteGear(Gear);
- exit
- end;
-
- HHGear^.State := HHGear^.State or gstNoDamage;
- DeleteCI(HHGear);
-
- Gear^.X := HHGear^.X;
- Gear^.Y := HHGear^.Y;
- if (GameTicks mod 2 = 0) and hasWishes then
- begin
- sparkles:= AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtDust, 1);
- if sparkles <> nil then
- begin
- sparkles^.Tint:= ((random(210)+45) shl 24) or ((random(210)+45) shl 16) or ((random(210)+45) shl 8) or $FF;
- sparkles^.Angle:= random(360);
- end
- end;
-
- i := 2;
- repeat
-
- Gear^.X := Gear^.X + HHGear^.dX;
- Gear^.Y := Gear^.Y + HHGear^.dY;
- HHGear^.X := Gear^.X;
- HHGear^.Y := Gear^.Y;
-
- inc(Gear^.Damage, 2);
-
- // if TestCollisionXwithGear(HHGear, hwSign(Gear^.dX))
- // or TestCollisionYwithGear(HHGear, hwSign(Gear^.dY)) then inc(Gear^.Damage, 3);
-
- dec(i)
- until (i = 0)
- or (Gear^.Damage > Gear^.Health);
-
- inc(upd);
- if upd > 3 then
- begin
- if Gear^.Health < 1500 then
- begin
- if Gear^.AdvBounce <> 0 then
- Gear^.Pos := 3
- else
- Gear^.Pos := 2;
- end;
-
- AmmoShove(Gear, 30, 40);
-
- DrawTunnel(HHGear^.X - HHGear^.dX * 10,
- HHGear^.Y - _2 - HHGear^.dY * 10 + hwAbs(HHGear^.dY) * 2,
- HHGear^.dX,
- HHGear^.dY,
- 20 + cHHRadius * 2,
- cHHRadius * 2 + 7);
-
- upd := 0
- end;
-
- if Gear^.Health < Gear^.Damage then
- begin
- doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, Gear^.Hedgehog, EXPLAutoSound);
- if hasWishes then
- for i:= 0 to 31 do
- begin
- sparkles:= AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtStraightShot);
- if sparkles <> nil then
- with sparkles^ do
- begin
- Tint:= ((random(210)+45) shl 24) or ((random(210)+45) shl 16) or ((random(210)+45) shl 8) or $FF;
- Angle:= random(360);
- dx:= 0.001 * (random(200));
- dy:= 0.001 * (random(200));
- if random(2) = 0 then
- dx := -dx;
- if random(2) = 0 then
- dy := -dy;
- FrameTicks:= random(400) + 250
- end
- end;
- AfterAttack;
- HHGear^.Message:= HHGear^.Message or gmDestroy;
- DeleteGear(Gear);
- end
- else
- begin
- dec(Gear^.Health, Gear^.Damage);
- Gear^.Damage := 0
- end
-end;
-
-procedure doStepKamikazeIdle(Gear: PGear);
-begin
- AllInactive := false;
- dec(Gear^.Timer);
- if Gear^.Timer = 0 then
- begin
- Gear^.Pos := 1;
- PlaySoundV(sndKamikaze, Gear^.Hedgehog^.Team^.voicepack);
- Gear^.doStep := @doStepKamikazeWork
- end
-end;
-
-procedure doStepKamikaze(Gear: PGear);
-var
- HHGear: PGear;
-begin
- AllInactive := false;
-
- HHGear := Gear^.Hedgehog^.Gear;
-
- HHGear^.dX := Gear^.dX;
- HHGear^.dY := Gear^.dY;
-
- Gear^.dX := SignAs(_0_45, Gear^.dX);
- Gear^.dY := - _0_9;
-
- Gear^.Timer := 550;
-
- Gear^.doStep := @doStepKamikazeIdle
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-
-const cakeh = 27;
-var
- CakePoints: array[0..Pred(cakeh)] of record
- x, y: hwFloat;
- end;
- CakeI: Longword;
-
-procedure doStepCakeExpl(Gear: PGear);
-begin
- AllInactive := false;
-
- inc(Gear^.Tag);
- if Gear^.Tag < 2250 then
- exit;
-
- doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), cakeDmg, Gear^.Hedgehog, EXPLAutoSound);
- AfterAttack;
- DeleteGear(Gear)
-end;
-
-procedure doStepCakeDown(Gear: PGear);
-var
- gi: PGear;
- dmg, dmgBase: LongInt;
- fX, fY, tdX, tdY: hwFloat;
-begin
- AllInactive := false;
-
- inc(Gear^.Tag);
- if Gear^.Tag < 100 then
- exit;
- Gear^.Tag := 0;
-
- if Gear^.Pos = 0 then
- begin
-///////////// adapted from doMakeExplosion ///////////////////////////
- //fX:= Gear^.X;
- //fY:= Gear^.Y;
- //fX.QWordValue:= fX.QWordValue and $FFFFFFFF00000000;
- //fY.QWordValue:= fY.QWordValue and $FFFFFFFF00000000;
- fX:= int2hwFloat(hwRound(Gear^.X));
- fY:= int2hwFloat(hwRound(Gear^.Y));
- dmgBase:= cakeDmg shl 1 + cHHRadius div 2;
- gi := GearsList;
- while gi <> nil do
- begin
- if gi^.Kind = gtHedgehog then
- begin
- dmg:= 0;
- tdX:= gi^.X-fX;
- tdY:= gi^.Y-fY;
- if hwRound(hwAbs(tdX)+hwAbs(tdY)) < dmgBase then
- dmg:= dmgBase - max(hwRound(Distance(tdX, tdY)),gi^.Radius);
- if (dmg > 1) then dmg:= ModifyDamage(min(dmg div 2, cakeDmg), gi);
- if (dmg > 1) then
- if (CurrentHedgehog^.Gear = gi) and (not gi^.Invulnerable) then
- gi^.State := gi^.State or gstLoser
- else
- gi^.State := gi^.State or gstWinner;
- end;
- gi := gi^.NextGear
- end;
-//////////////////////////////////////////////////////////////////////
- Gear^.doStep := @doStepCakeExpl;
- PlaySound(sndCake)
- end
- else dec(Gear^.Pos)
-end;
-
-
-procedure doStepCakeWork(Gear: PGear);
-var
- tdx, tdy: hwFloat;
-begin
- AllInactive := false;
-
- inc(Gear^.Tag);
- if Gear^.Tag < 7 then
- exit;
-
- dec(Gear^.Health);
- Gear^.Timer := Gear^.Health*10;
- if Gear^.Health mod 100 = 0 then
- Gear^.PortalCounter:= 0;
- // This is not seconds, but at least it is *some* feedback
- if (Gear^.Health = 0) or ((Gear^.Message and gmAttack) <> 0) then
- begin
- FollowGear := Gear;
- Gear^.RenderTimer := false;
- Gear^.doStep := @doStepCakeDown;
- exit
- end;
-
- cakeStep(Gear);
-
- if Gear^.Tag = 0 then
- begin
- CakeI := (CakeI + 1) mod cakeh;
- tdx := CakePoints[CakeI].x - Gear^.X;
- tdy := - CakePoints[CakeI].y + Gear^.Y;
- CakePoints[CakeI].x := Gear^.X;
- CakePoints[CakeI].y := Gear^.Y;
- Gear^.DirAngle := DxDy2Angle(tdx, tdy);
- end;
-end;
-
-procedure doStepCakeUp(Gear: PGear);
-var
- i: Longword;
-begin
- AllInactive := false;
-
- inc(Gear^.Tag);
- if Gear^.Tag < 100 then
- exit;
- Gear^.Tag := 0;
-
- if Gear^.Pos = 6 then
- begin
- for i:= 0 to Pred(cakeh) do
- begin
- CakePoints[i].x := Gear^.X;
- CakePoints[i].y := Gear^.Y
- end;
- CakeI := 0;
- Gear^.doStep := @doStepCakeWork
- end
- else
- inc(Gear^.Pos)
-end;
-
-procedure doStepCakeFall(Gear: PGear);
-begin
- AllInactive := false;
-
- Gear^.dY := Gear^.dY + cGravity;
- if TestCollisionYwithGear(Gear, 1) <> 0 then
- Gear^.doStep := @doStepCakeUp
- else
- begin
- Gear^.Y := Gear^.Y + Gear^.dY;
- if CheckGearDrowning(Gear) then
- AfterAttack
- end
-end;
-
-procedure doStepCake(Gear: PGear);
-var
- HHGear: PGear;
-begin
- AllInactive := false;
-
- HHGear := Gear^.Hedgehog^.Gear;
- HHGear^.Message := HHGear^.Message and (not gmAttack);
- Gear^.CollisionMask:= lfNotCurrentMask;
-
- FollowGear := Gear;
-
- Gear^.doStep := @doStepCakeFall
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepSeductionWork(Gear: PGear);
-var i: LongInt;
- hogs: PGearArrayS;
-begin
- AllInactive := false;
- hogs := GearsNear(Gear^.X, Gear^.Y, gtHedgehog, Gear^.Radius);
- if hogs.size > 0 then
- begin
- for i:= 0 to hogs.size - 1 do
- with hogs.ar^[i]^ do
- begin
- if hogs.ar^[i] <> CurrentHedgehog^.Gear then
- begin
- dX:= _50 * cGravity * (Gear^.X - X) / _25;
- dY:= -_450 * cGravity;
- Active:= true;
- end
- end;
- end ;
- AfterAttack;
- DeleteGear(Gear);
-(*
- Gear^.X := Gear^.X + Gear^.dX;
- Gear^.Y := Gear^.Y + Gear^.dY;
- x := hwRound(Gear^.X);
- y := hwRound(Gear^.Y);
-
- if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) then
- if (Land[y, x] <> 0) then
- begin
- Gear^.dX.isNegative := not Gear^.dX.isNegative;
- Gear^.dY.isNegative := not Gear^.dY.isNegative;
- Gear^.dX := Gear^.dX * _1_5;
- Gear^.dY := Gear^.dY * _1_5 - _0_3;
- AmmoShove(Gear, 0, 40);
- AfterAttack;
- DeleteGear(Gear)
- end
- else
- else
- begin
- AfterAttack;
- DeleteGear(Gear)
- end*)
-end;
-
-procedure doStepSeductionWear(Gear: PGear);
-var heart: PVisualGear;
-begin
- AllInactive := false;
- inc(Gear^.Timer);
- if Gear^.Timer > 250 then
- begin
- Gear^.Timer := 0;
- inc(Gear^.Pos);
- if Gear^.Pos = 5 then
- PlaySoundV(sndYoohoo, Gear^.Hedgehog^.Team^.voicepack)
- end;
-
- if (Gear^.Pos = 14) and (RealTicks and $3 = 0) then
- begin
- heart:= AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtStraightShot);
- if heart <> nil then
- with heart^ do
- begin
- dx:= 0.001 * (random(200));
- dy:= 0.001 * (random(200));
- if random(2) = 0 then
- dx := -dx;
- if random(2) = 0 then
- dy := -dy;
- FrameTicks:= random(750) + 1000;
- State:= ord(sprSeduction)
- end;
- end;
-
- if Gear^.Pos = 15 then
- Gear^.doStep := @doStepSeductionWork
-end;
-
-procedure doStepSeduction(Gear: PGear);
-begin
- AllInactive := false;
- //DeleteCI(Gear^.Hedgehog^.Gear);
- Gear^.doStep := @doStepSeductionWear
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepWaterUp(Gear: PGear);
-var
- i: LongWord;
-begin
- if (Gear^.Tag = 0)
- or (cWaterLine = 0) then
- begin
- DeleteGear(Gear);
- exit
- end;
-
- AllInactive := false;
-
- inc(Gear^.Timer);
- if Gear^.Timer = 17 then
- Gear^.Timer := 0
- else
- exit;
-
- if cWaterLine > 0 then
- begin
- dec(cWaterLine);
- for i:= 0 to LAND_WIDTH - 1 do
- Land[cWaterLine, i] := 0;
- SetAllToActive
- end;
-
- dec(Gear^.Tag);
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepDrill(Gear: PGear);
-forward;
-
-procedure doStepDrillDrilling(Gear: PGear);
-var
- t: PGearArray;
- tempColl: Word;
-begin
- AllInactive := false;
- if (Gear^.Timer > 0) and (Gear^.Timer mod 10 <> 0) then
- begin
- dec(Gear^.Timer);
- exit;
- end;
-
- DrawTunnel(Gear^.X, Gear^.Y, Gear^.dX, Gear^.dY, 2, 6);
- Gear^.X := Gear^.X + Gear^.dX;
- Gear^.Y := Gear^.Y + Gear^.dY;
- if (Gear^.Timer mod 30) = 0 then
- AddVisualGear(hwRound(Gear^.X + _20 * Gear^.dX), hwRound(Gear^.Y + _20 * Gear^.dY), vgtDust);
- if (CheckGearDrowning(Gear)) then
- begin
- StopSoundChan(Gear^.SoundChannel);
- exit
- end;
-
- tempColl:= Gear^.CollisionMask;
- Gear^.CollisionMask:= $007F;
- if (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) <> 0) or TestCollisionXWithGear(Gear, hwSign(Gear^.dX)) or (GameTicks > Gear^.FlightTime) then
- t := CheckGearsCollision(Gear)
- else t := nil;
- Gear^.CollisionMask:= tempColl;
- //fixes drill not exploding when touching HH bug
-
- if (Gear^.Timer = 0) or ((t <> nil) and (t^.Count <> 0))
- or ( ((Gear^.State and gsttmpFlag) = 0) and (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) = 0) and (not TestCollisionXWithGear(Gear, hwSign(Gear^.dX))))
-// CheckLandValue returns true if the type isn't matched
- or (not CheckLandValue(hwRound(Gear^.X), hwRound(Gear^.Y), lfIndestructible)) then
- begin
- //out of time or exited ground
- StopSoundChan(Gear^.SoundChannel);
- if (Gear^.State and gsttmpFlag) <> 0 then
- doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, Gear^.Hedgehog, EXPLAutoSound)
- else
- doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound);
- DeleteGear(Gear);
- exit
- end
-
- else if (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) = 0) and (not TestCollisionXWithGear(Gear, hwSign(Gear^.dX))) then
- begin
- StopSoundChan(Gear^.SoundChannel);
- Gear^.Tag := 1;
- Gear^.doStep := @doStepDrill
- end;
-
- dec(Gear^.Timer);
-end;
-
-procedure doStepDrill(Gear: PGear);
-var
- t: PGearArray;
- oldDx, oldDy: hwFloat;
- t2: hwFloat;
-begin
- AllInactive := false;
-
- if (Gear^.State and gsttmpFlag) = 0 then
- Gear^.dX := Gear^.dX + cWindSpeed;
-
- oldDx := Gear^.dX;
- oldDy := Gear^.dY;
-
- doStepFallingGear(Gear);
-
- if (GameTicks and $3F) = 0 then
- begin
- if hwRound(Gear^.Y) > cWaterLine then
- AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtBubble)
- else AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace)
- end;
-
- if ((Gear^.State and gstCollision) <> 0) then
- begin
- //hit
- Gear^.dX := oldDx;
- Gear^.dY := oldDy;
-
- if GameTicks > Gear^.FlightTime then
- t := CheckGearsCollision(Gear)
- else
- t := nil;
- if (t = nil) or (t^.Count = 0) then
- begin
- //hit the ground not the HH
- t2 := _0_5 / Distance(Gear^.dX, Gear^.dY);
- Gear^.dX := Gear^.dX * t2;
- Gear^.dY := Gear^.dY * t2;
- end
-
- else if (t <> nil) then
- begin
- //explode right on contact with HH
- if (Gear^.State and gsttmpFlag) <> 0 then
- doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, Gear^.Hedgehog, EXPLAutoSound)
- else
- doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound);
- DeleteGear(Gear);
- exit;
- end;
-
- Gear^.SoundChannel := LoopSound(sndDrillRocket);
- Gear^.doStep := @doStepDrillDrilling;
-
- if (Gear^.State and gsttmpFlag) <> 0 then
- gear^.RenderTimer:= true;
- if Gear^.Timer > 0 then dec(Gear^.Timer)
- end
- else if ((Gear^.State and gsttmpFlag) <> 0) and (Gear^.Tag <> 0) then
- begin
- if Gear^.Timer > 0 then
- dec(Gear^.Timer)
- else
- begin
- doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, Gear^.Hedgehog, EXPLAutoSound);
- DeleteGear(Gear);
- end
- end;
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepBallgunWork(Gear: PGear);
-var
- HHGear, ball: PGear;
- rx, ry: hwFloat;
- gX, gY: LongInt;
-begin
- AllInactive := false;
- dec(Gear^.Timer);
- HHGear := Gear^.Hedgehog^.Gear;
- HedgehogChAngle(HHGear);
- gX := hwRound(Gear^.X) + GetLaunchX(amBallgun, hwSign(HHGear^.dX), HHGear^.Angle);
- gY := hwRound(Gear^.Y) + GetLaunchY(amBallgun, HHGear^.Angle);
- if (Gear^.Timer mod 100) = 0 then
- begin
- rx := rndSign(getRandomf * _0_1);
- ry := rndSign(getRandomf * _0_1);
-
- ball:= AddGear(gx, gy, gtBall, 0, SignAs(AngleSin(HHGear^.Angle) * _0_8, HHGear^.dX) + rx, AngleCos(HHGear^.Angle) * ( - _0_8) + ry, 0);
- ball^.CollisionMask:= lfNotCurrentMask;
-
- PlaySound(sndGun);
- end;
-
- if (Gear^.Timer = 0) or ((HHGear^.State and gstHHDriven) = 0) then
- begin
- DeleteGear(Gear);
- AfterAttack
- end
-end;
-
-procedure doStepBallgun(Gear: PGear);
-var
- HHGear: PGear;
-begin
- HHGear := Gear^.Hedgehog^.Gear;
- HHGear^.Message := HHGear^.Message and (not (gmUp or gmDown));
- HHGear^.State := HHGear^.State or gstNotKickable;
- Gear^.doStep := @doStepBallgunWork
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepRCPlaneWork(Gear: PGear);
-
-const cAngleSpeed = 3;
-var
- HHGear: PGear;
- i: LongInt;
- dX, dY: hwFloat;
- fChanged: boolean;
- trueAngle: Longword;
- t: PGear;
-begin
- AllInactive := false;
-
- HHGear := Gear^.Hedgehog^.Gear;
- FollowGear := Gear;
-
- if Gear^.Timer > 0 then
- dec(Gear^.Timer);
-
- fChanged := false;
- if ((HHGear^.State and gstHHDriven) = 0) or (Gear^.Timer = 0) then
- begin
- fChanged := true;
- if Gear^.Angle > 2048 then
- dec(Gear^.Angle)
- else if Gear^.Angle < 2048 then
- inc(Gear^.Angle)
- else fChanged := false
- end
- else
- begin
- if ((Gear^.Message and gmLeft) <> 0) then
- begin
- fChanged := true;
- Gear^.Angle := (Gear^.Angle + (4096 - cAngleSpeed)) mod 4096
- end;
-
- if ((Gear^.Message and gmRight) <> 0) then
- begin
- fChanged := true;
- Gear^.Angle := (Gear^.Angle + cAngleSpeed) mod 4096
- end
- end;
-
- if fChanged then
- begin
- Gear^.dX.isNegative := (Gear^.Angle > 2048);
- if Gear^.dX.isNegative then
- trueAngle := 4096 - Gear^.Angle
- else
- trueAngle := Gear^.Angle;
-
- Gear^.dX := SignAs(AngleSin(trueAngle), Gear^.dX) * _0_25;
- Gear^.dY := AngleCos(trueAngle) * -_0_25;
- end;
-
- Gear^.X := Gear^.X + Gear^.dX;
- Gear^.Y := Gear^.Y + Gear^.dY;
-
- if (GameTicks and $FF) = 0 then
- if Gear^.Timer < 3500 then
- AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtEvilTrace)
- else
- AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace);
-
- if ((HHGear^.Message and gmAttack) <> 0) and (Gear^.Health <> 0) then
- begin
- HHGear^.Message := HHGear^.Message and (not gmAttack);
- AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtAirBomb, 0, Gear^.dX * _0_5, Gear^.dY *
- _0_5, 0);
- dec(Gear^.Health)
- end;
-
- if ((HHGear^.Message and gmLJump) <> 0) and ((Gear^.State and gsttmpFlag) = 0) then
- begin
- Gear^.State := Gear^.State or gsttmpFlag;
- PauseMusic;
- playSound(sndRideOfTheValkyries);
- end;
-
- // pickup bonuses
- t := CheckGearNear(Gear, gtCase, 36, 36);
- if t <> nil then
- PickUp(HHGear, t);
-
- CheckCollision(Gear);
-
- if ((Gear^.State and gstCollision) <> 0) or CheckGearDrowning(Gear) then
- begin
- StopSoundChan(Gear^.SoundChannel);
- StopSound(sndRideOfTheValkyries);
- ResumeMusic;
-
- if ((Gear^.State and gstCollision) <> 0) then
- begin
- doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 25, Gear^.Hedgehog, EXPLAutoSound);
- for i:= 0 to 15 do
- begin
- dX := AngleCos(i * 64) * _0_5 * (GetRandomf + _1);
- dY := AngleSin(i * 64) * _0_5 * (GetRandomf + _1);
- AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtFlame, 0, dX, dY, 0);
- AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtFlame, 0, dX, -dY, 0);
- end;
- DeleteGear(Gear)
- end;
-
- AfterAttack;
- CurAmmoGear := nil;
- if (GameFlags and gfInfAttack) = 0 then
- begin
- if TagTurnTimeLeft = 0 then
- TagTurnTimeLeft:= TurnTimeLeft;
-
- TurnTimeLeft:= 14 * 125;
- end;
-
- HHGear^.Message := 0;
- ParseCommand('/taunt ' + #1, true)
- end
-end;
-
-procedure doStepRCPlane(Gear: PGear);
-var
- HHGear: PGear;
-begin
- HHGear := Gear^.Hedgehog^.Gear;
- HHGear^.Message := 0;
- HHGear^.State := HHGear^.State or gstNotKickable;
- Gear^.Angle := HHGear^.Angle;
- Gear^.Tag := hwSign(HHGear^.dX);
-
- if HHGear^.dX.isNegative then
- Gear^.Angle := 4096 - Gear^.Angle;
- Gear^.doStep := @doStepRCPlaneWork
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepJetpackWork(Gear: PGear);
-var
- HHGear: PGear;
- fuel, i: LongInt;
- move: hwFloat;
- isUnderwater: Boolean;
- bubble: PVisualGear;
-begin
- isUnderwater:= cWaterLine < hwRound(Gear^.Y) + Gear^.Radius;
- if Gear^.Pos > 0 then
- dec(Gear^.Pos);
- AllInactive := false;
- HHGear := Gear^.Hedgehog^.Gear;
- //dec(Gear^.Timer);
- move := _0_2;
- fuel := 50;
-(*if (HHGear^.Message and gmPrecise) <> 0 then
- begin
- move:= _0_02;
- fuel:= 5;
- end;*)
- if HHGear^.Message and gmPrecise <> 0 then
- HedgehogChAngle(HHGear)
- else if Gear^.Health > 0 then
- begin
- if HHGear^.Message and gmUp <> 0 then
- begin
- if (not HHGear^.dY.isNegative) or (HHGear^.Y > -_256) then
- begin
- if isUnderwater then
- begin
- HHGear^.dY := HHGear^.dY - (move * _0_7);
- for i:= random(10)+10 downto 0 do
- begin
- bubble := AddVisualGear(hwRound(HHGear^.X) - 8 + random(16), hwRound(HHGear^.Y) + 16 + random(8), vgtBubble);
- if bubble <> nil then
- bubble^.dY:= random(20)/10+0.1;
- end
- end
- else HHGear^.dY := HHGear^.dY - move;
- end;
- dec(Gear^.Health, fuel);
- Gear^.MsgParam := Gear^.MsgParam or gmUp;
- Gear^.Timer := GameTicks
- end;
- move.isNegative := (HHGear^.Message and gmLeft) <> 0;
- if (HHGear^.Message and (gmLeft or gmRight)) <> 0 then
- begin
- HHGear^.dX := HHGear^.dX + (move * _0_1);
- if isUnderwater then
- begin
- for i:= random(5)+5 downto 0 do
- begin
- bubble := AddVisualGear(hwRound(HHGear^.X)+random(8), hwRound(HHGear^.Y) - 8 + random(16), vgtBubble);
- if bubble <> nil then
- begin
- bubble^.dX:= (random(10)/10 + 0.02) * -1;
- if (move.isNegative) then
- begin
- bubble^.X := bubble^.X + 28;
- bubble^.dX:= bubble^.dX * (-1)
- end
- else bubble^.X := bubble^.X - 28;
- end;
- end
- end;
- dec(Gear^.Health, fuel div 5);
- Gear^.MsgParam := Gear^.MsgParam or (HHGear^.Message and (gmLeft or gmRight));
- Gear^.Timer := GameTicks
- end
- end;
-
- // erases them all at once :-/
- if (Gear^.Timer <> 0) and (GameTicks - Gear^.Timer > 250) then
- begin
- Gear^.Timer := 0;
- Gear^.MsgParam := 0
- end;
-
- if Gear^.Health < 0 then
- Gear^.Health := 0;
-
- i:= Gear^.Health div 20;
-
- if (i <> Gear^.Damage) and ((GameTicks and $3F) = 0) then
- begin
- Gear^.Damage:= i;
- //AddCaption('Fuel: '+inttostr(round(Gear^.Health/20))+'%', cWhiteColor, capgrpAmmostate);
- FreeTexture(Gear^.Tex);
- Gear^.Tex := RenderStringTex(trmsg[sidFuel] + ': ' + inttostr(i) + '%', cWhiteColor, fntSmall)
- end;
-
- if (HHGear^.Message and (gmAttack or gmUp or gmLeft or gmRight) <> 0) and
- (HHGear^.Message and gmPrecise = 0) then
- Gear^.State := Gear^.State and (not gsttmpFlag);
-
- if HHGear^.Message and gmPrecise = 0 then
- HHGear^.Message := HHGear^.Message and (not (gmUp or gmLeft or gmRight));
- HHGear^.State := HHGear^.State or gstMoving;
-
- Gear^.X := HHGear^.X;
- Gear^.Y := HHGear^.Y;
-
- if not isUnderWater and hasBorder and ((HHGear^.X < _0)
- or (hwRound(HHGear^.X) > LAND_WIDTH)) then
- HHGear^.dY.isNegative:= false;
-
- if ((Gear^.State and gsttmpFlag) = 0)
- or (HHGear^.dY < _0) then
- doStepHedgehogMoving(HHGear);
-
- if // (Gear^.Health = 0)
- (HHGear^.Damage <> 0)
- //or CheckGearDrowning(HHGear)
- or (cWaterLine + cVisibleWater * 4 < hwRound(HHGear^.Y))
- or (TurnTimeLeft = 0)
- // allow brief ground touches - to be fair on this, might need another counter
- or (((GameTicks and $1FF) = 0) and (not HHGear^.dY.isNegative) and (TestCollisionYwithGear(HHGear, 1) <> 0))
- or ((Gear^.Message and gmAttack) <> 0) then
- begin
- with HHGear^ do
- begin
- Message := 0;
- Active := true;
- State := State or gstMoving
- end;
- DeleteGear(Gear);
- isCursorVisible := false;
- ApplyAmmoChanges(HHGear^.Hedgehog^);
- // if Gear^.Tex <> nil then FreeTexture(Gear^.Tex);
-
-// Gear^.Tex:= RenderStringTex(trmsg[sidFuel] + ': ' + inttostr(round(Gear^.Health / 20)) + '%', cWhiteColor, fntSmall)
-
-//AddCaption(trmsg[sidFuel]+': '+inttostr(round(Gear^.Health/20))+'%', cWhiteColor, capgrpAmmostate);
- end
-end;
-
-procedure doStepJetpack(Gear: PGear);
-var
- HHGear: PGear;
-begin
- Gear^.Pos:= 0;
- Gear^.doStep := @doStepJetpackWork;
-
- HHGear := Gear^.Hedgehog^.Gear;
- FollowGear := HHGear;
- AfterAttack;
- with HHGear^ do
- begin
- State := State and (not gstAttacking);
- Message := Message and (not (gmAttack or gmUp or gmPrecise or gmLeft or gmRight));
-
- if (dY < _0_1) and (dY > -_0_1) then
- begin
- Gear^.State := Gear^.State or gsttmpFlag;
- dY := dY - _0_2
- end
- end
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepBirdyDisappear(Gear: PGear);
-begin
- AllInactive := false;
- Gear^.Pos := 0;
- if Gear^.Timer < 2000 then
- inc(Gear^.Timer, 1)
- else
- begin
- DeleteGear(Gear);
- end;
-end;
-
-procedure doStepBirdyFly(Gear: PGear);
-var
- HHGear: PGear;
- fuel, i: LongInt;
- move: hwFloat;
-begin
- HHGear := Gear^.Hedgehog^.Gear;
- if HHGear = nil then
- begin
- DeleteGear(Gear);
- exit
- end;
-
- move := _0_2;
- fuel := 50;
-
- if Gear^.Pos > 0 then
- dec(Gear^.Pos, 1)
- else if (HHGear^.Message and (gmLeft or gmRight or gmUp)) <> 0 then
- Gear^.Pos := 500;
-
- if HHGear^.dX.isNegative then
- Gear^.Tag := -1
- else
- Gear^.Tag := 1;
-
- if (HHGear^.Message and gmUp) <> 0 then
- begin
- if (not HHGear^.dY.isNegative)
- or (HHGear^.Y > -_256) then
- HHGear^.dY := HHGear^.dY - move;
-
- dec(Gear^.Health, fuel);
- Gear^.MsgParam := Gear^.MsgParam or gmUp;
- end;
-
- if (HHGear^.Message and gmLeft) <> 0 then move.isNegative := true;
- if (HHGear^.Message and (gmLeft or gmRight)) <> 0 then
- begin
- HHGear^.dX := HHGear^.dX + (move * _0_1);
- dec(Gear^.Health, fuel div 5);
- Gear^.MsgParam := Gear^.MsgParam or (HHGear^.Message and (gmLeft or gmRight));
- end;
-
- if Gear^.Health < 0 then
- Gear^.Health := 0;
-
- if ((GameTicks and $FF) = 0) and (Gear^.Health < 500) then
- for i:= ((500-Gear^.Health) div 250) downto 0 do
- AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtFeather);
-
- if (HHGear^.Message and gmAttack <> 0) then
- begin
- HHGear^.Message := HHGear^.Message and (not gmAttack);
- if Gear^.FlightTime > 0 then
- begin
- AddGear(hwRound(Gear^.X), hwRound(Gear^.Y) + 32, gtEgg, 0, Gear^.dX * _0_5, Gear^.dY, 0);
- PlaySound(sndBirdyLay);
- dec(Gear^.FlightTime)
- end;
- end;
-
- if HHGear^.Message and (gmUp or gmPrecise or gmLeft or gmRight) <> 0 then
- Gear^.State := Gear^.State and (not gsttmpFlag);
-
- HHGear^.Message := HHGear^.Message and (not (gmUp or gmPrecise or gmLeft or gmRight));
- HHGear^.State := HHGear^.State or gstMoving;
-
- Gear^.X := HHGear^.X;
- Gear^.Y := HHGear^.Y - int2hwFloat(32);
- // For some reason I need to reapply followgear here, something else grabs it otherwise.
- // this is probably not needed anymore
- if not CurrentTeam^.ExtDriven then FollowGear := HHGear;
-
- if ((Gear^.State and gsttmpFlag) = 0)
- or (HHGear^.dY < _0) then
- doStepHedgehogMoving(HHGear);
-
- if (Gear^.Health = 0)
- or (HHGear^.Damage <> 0)
- or CheckGearDrowning(HHGear)
- or (TurnTimeLeft = 0)
- // allow brief ground touches - to be fair on this, might need another counter
- or (((GameTicks and $1FF) = 0) and (not HHGear^.dY.isNegative) and (TestCollisionYwithGear(HHGear, 1) <> 0))
- or ((Gear^.Message and gmAttack) <> 0) then
- begin
- with HHGear^ do
- begin
- Message := 0;
- Active := true;
- State := State or gstMoving
- end;
- Gear^.State := Gear^.State or gstAnimation or gstTmpFlag;
- if HHGear^.dY < _0 then
- begin
- Gear^.dX := HHGear^.dX;
- Gear^.dY := HHGear^.dY;
- end;
- Gear^.Timer := 0;
- Gear^.doStep := @doStepBirdyDisappear;
- CurAmmoGear := nil;
- isCursorVisible := false;
- AfterAttack;
- end
-end;
-
-procedure doStepBirdyDescend(Gear: PGear);
-var
- HHGear: PGear;
-begin
- if Gear^.Timer > 0 then
- dec(Gear^.Timer, 1)
- else if Gear^.Hedgehog^.Gear = nil then
- begin
- DeleteGear(Gear);
- AfterAttack;
- exit
- end;
- HHGear := Gear^.Hedgehog^.Gear;
- HHGear^.Message := HHGear^.Message and (not (gmUp or gmPrecise or gmLeft or gmRight));
- if abs(hwRound(HHGear^.Y - Gear^.Y)) > 32 then
- begin
- if Gear^.Timer = 0 then
- Gear^.Y := Gear^.Y + _0_1
- end
- else if Gear^.Timer = 0 then
- begin
- Gear^.doStep := @doStepBirdyFly;
- HHGear^.dY := -_0_2
- end
-end;
-
-procedure doStepBirdyAppear(Gear: PGear);
-begin
- Gear^.Pos := 0;
- if Gear^.Timer < 2000 then
- inc(Gear^.Timer, 1)
- else
- begin
- Gear^.Timer := 500;
- Gear^.dX := _0;
- Gear^.dY := _0;
- Gear^.State := Gear^.State and (not gstAnimation);
- Gear^.doStep := @doStepBirdyDescend;
- end
-end;
-
-procedure doStepBirdy(Gear: PGear);
-var
- HHGear: PGear;
-begin
- gear^.State := gear^.State or gstAnimation and (not gstTmpFlag);
- Gear^.doStep := @doStepBirdyAppear;
-
- if CurrentHedgehog = nil then
- begin
- DeleteGear(Gear);
- exit
- end;
-
- HHGear := CurrentHedgehog^.Gear;
-
- if HHGear^.dX.isNegative then
- Gear^.Tag := -1
- else
- Gear^.Tag := 1;
- Gear^.Pos := 0;
- AllInactive := false;
- FollowGear := HHGear;
- with HHGear^ do
- begin
- State := State and (not gstAttacking);
- Message := Message and (not (gmAttack or gmUp or gmPrecise or gmLeft or gmRight))
- end
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepEggWork(Gear: PGear);
-var
- vg: PVisualGear;
- i: LongInt;
-begin
- AllInactive := false;
- Gear^.dX := Gear^.dX;
- doStepFallingGear(Gear);
- // CheckGearDrowning(Gear); // already checked for in doStepFallingGear
- CalcRotationDirAngle(Gear);
-
- if (Gear^.State and gstCollision) <> 0 then
- begin
- doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 10, Gear^.Hedgehog, EXPLPoisoned, $C0E0FFE0);
- PlaySound(sndEggBreak);
- AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtEgg);
- vg := AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtEgg);
- if vg <> nil then
- vg^.Frame := 2;
-
- for i:= 10 downto 0 do
- begin
- vg := AddVisualGear(hwRound(Gear^.X) - 3 + Random(6), hwRound(Gear^.Y) - 3 + Random(6),
- vgtDust);
- if vg <> nil then
- vg^.dX := vg^.dX + (Gear^.dX.QWordValue / 21474836480);
- end;
-
- DeleteGear(Gear);
- exit
- end;
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doPortalColorSwitch();
-var CurWeapon: PAmmo;
-begin
- if (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil) and ((CurrentHedgehog^.Gear^.Message and gmSwitch) <> 0) then
- with CurrentHedgehog^ do
- if (CurAmmoType = amPortalGun) then
- begin
- CurrentHedgehog^.Gear^.Message := CurrentHedgehog^.Gear^.Message and (not gmSwitch);
-
- CurWeapon:= GetCurAmmoEntry(CurrentHedgehog^);
- if CurWeapon^.Pos <> 0 then
- CurWeapon^.Pos := 0
-
- else
- CurWeapon^.Pos := 1;
- end;
-end;
-
-procedure doStepPortal(Gear: PGear);
-var
- iterator, conPortal: PGear;
- s, r, nx, ny, ox, oy, poffs, noffs, pspeed, nspeed,
- resetx, resety, resetdx, resetdy: hwFloat;
- sx, sy, rh, resetr: LongInt;
- hasdxy, isbullet, iscake, isCollision: Boolean;
-begin
- doPortalColorSwitch();
-
- // destroy portal if ground it was attached too is gone
- if (Land[hwRound(Gear^.Y), hwRound(Gear^.X)] <= lfAllObjMask)
- or (Gear^.Timer < 1)
- or (Gear^.Hedgehog^.Team <> CurrentHedgehog^.Team)
- or (hwRound(Gear^.Y) > cWaterLine) then
- begin
- deleteGear(Gear);
- EXIT;
- end;
-
- if (TurnTimeLeft < 1)
- or (Gear^.Health < 1) then
- dec(Gear^.Timer);
-
- if Gear^.Timer < 10000 then
- gear^.RenderTimer := true;
-
- // abort if there is no other portal connected to this one
- if (Gear^.LinkedGear = nil) then
- exit;
- if ((Gear^.LinkedGear^.Tag and 1) = 0) then // or if it's still moving;
- exit;
-
- conPortal := Gear^.LinkedGear;
-
- // check all gears for stuff to port through
- iterator := nil;
- while true do
- begin
-
- // iterate through GearsList
- if iterator = nil then
- iterator := GearsList
- else
- iterator := iterator^.NextGear;
-
- // end of list?
- if iterator = nil then
- break;
-
- // don't port portals or other gear that wouldn't make sense
- if (iterator^.Kind in [gtPortal, gtRope, gtAirAttack, gtIceGun])
- or (iterator^.PortalCounter > 32) then
- continue;
-
- // don't port hogs on rope
- // TODO: this will also prevent hogs while falling after rope use from
- // falling through portals... fix that!
-
- // check if gear fits through portal
- if (iterator^.Radius > Gear^.Radius) then
- continue;
-
- // this is the max range we accept incoming gears in
- r := Int2hwFloat(iterator^.Radius+Gear^.Radius);
-
- // too far away?
- if (iterator^.X < Gear^.X - r)
- or (iterator^.X > Gear^.X + r)
- or (iterator^.Y < Gear^.Y - r)
- or (iterator^.Y > Gear^.Y + r) then
- continue;
-
- hasdxy := (((iterator^.dX.QWordValue <> 0) or (iterator^.dY.QWordValue <> 0)) or ((iterator^.State or gstMoving) = 0));
-
- // in case the object is not moving, let's asume it's falling towards the portal
- if not hasdxy then
- begin
- if Gear^.Y < iterator^.Y then
- continue;
- ox:= Gear^.X - iterator^.X;
- oy:= Gear^.Y - iterator^.Y;
- end
- else
- begin
- ox:= iterator^.dX;
- oy:= iterator^.dY;
- end;
-
- // cake will need extra treatment... it's so delicious and moist!
- iscake:= (iterator^.Kind = gtCake);
-
- // won't port stuff that does not move towards the front/portal entrance
- if iscake then
- begin
- if not (((iterator^.X - Gear^.X)*ox + (iterator^.Y - Gear^.Y)*oy).isNegative) then
- continue;
- end
- else
- if not ((Gear^.dX*ox + Gear^.dY*oy).isNegative) then
- continue;
-
- isbullet:= (iterator^.Kind in [gtShotgunShot, gtDEagleShot, gtSniperRifleShot, gtSineGunShot]);
-
- r:= int2hwFloat(iterator^.Radius);
-
- if not (isbullet or iscake) then
- begin
- // wow! good candidate there, let's see if the distance and direction is okay!
- if hasdxy then
- begin
- s := Distance(iterator^.dX, iterator^.dY);
- // if the resulting distance is 0 skip this gear
- if s.QWordValue = 0 then
- continue;
- s := r / s;
- ox:= iterator^.X + s * iterator^.dX;
- oy:= iterator^.Y + s * iterator^.dY;
- end
- else
- begin
- ox:= iterator^.X;
- oy:= iterator^.Y + r;
- end;
-
- if (hwRound(Distance(Gear^.X-ox,Gear^.Y-oy)) > Gear^.Radius + 1 ) then
- continue;
- end;
-
- // draw bullet trail
- if isbullet then
- spawnBulletTrail(iterator);
-
- // calc gear offset in portal vector direction
- ox := (iterator^.X - Gear^.X);
- oy := (iterator^.Y - Gear^.Y);
- poffs:= (Gear^.dX * ox + Gear^.dY * oy);
-
- if not isBullet and poffs.isNegative then
- continue;
-
- // only port bullets close to the portal
- if isBullet and (not (hwAbs(poffs) < _3)) then
- continue;
-
- //
- // gears that make it till here will definately be ported
- //
- // (but old position/movement vector might be restored in case there's
- // not enough space on the other side)
- //
-
- resetr := iterator^.Radius;
- resetx := iterator^.X;
- resety := iterator^.Y;
- resetdx := iterator^.dX;
- resetdy := iterator^.dY;
-
- // create a normal of the portal vector, but ...
- nx := Gear^.dY;
- ny := Gear^.dX;
- // ... decide where the top is based on the hog's direction when firing the portal
- if Gear^.Elasticity.isNegative then
- nx.isNegative := (not nx.isNegative)
- else
- ny.isNegative := not ny.isNegative;
-
- // calc gear offset in portal normal vector direction
- noffs:= (nx * ox + ny * oy);
-
- if isBullet and (noffs.Round >= Longword(Gear^.Radius)) then
- continue;
-
- // avoid gravity related loops of not really moving gear
- if not (iscake or isbullet)
- and (Gear^.dY.isNegative)
- and (conPortal^.dY.isNegative)
- and ((iterator^.dX.QWordValue + iterator^.dY.QWordValue) < _0_08.QWordValue)
- and (iterator^.PortalCounter > 0) then
- continue;
-
- // calc gear speed along to the vector and the normal vector of the portal
- if hasdxy then
- begin
- pspeed:= (Gear^.dX * iterator^.dX + Gear^.dY * iterator^.dY);
- nspeed:= (nx * iterator^.dX + ny * iterator^.dY);
- end
- else
- begin
- pspeed:= hwAbs(cGravity * oy);
- nspeed:= _0;
- end;
-
- // creating normal vector of connected (exit) portal
- nx := conPortal^.dY;
- ny := conPortal^.dX;
- if conPortal^.Elasticity.isNegative then
- nx.isNegative := (not nx.isNegative)
- else
- ny.isNegative := not ny.isNegative;
-
- // inverse cake's normal movement direction,
- // as if it just walked through a hole
- //if iscake then nspeed.isNegative:= not nspeed.isNegative;
-
-//AddFileLog('poffs:'+cstr(poffs)+' noffs:'+cstr(noffs)+' pspeed:'+cstr(pspeed)+' nspeed:'+cstr(nspeed));
- iterator^.dX := -pspeed * conPortal^.dX + nspeed * nx;
- iterator^.dY := -pspeed * conPortal^.dY + nspeed * ny;
-
- // make the gear's exit position close to the portal while
- // still respecting the movement direction
-
- // determine the distance (in exit vector direction)
- // that we want the gear at
- if iscake then
- ox:= (r - _0_7)
- else
- ox:= (r * _1_5);
- s:= ox / poffs;
- poffs:= ox;
- if (nspeed.QWordValue <> 0)
- and (pspeed > _0) then
- noffs:= noffs * s * (nspeed / pspeed);
-
- // move stuff with high normal offset closer to the portal's center
- if not isbullet then
- begin
- s := hwAbs(noffs) + r - int2hwFloat(Gear^.Radius);
- if s > _0 then
- noffs:= noffs - SignAs(s,noffs)
- end;
-
- iterator^.X := conPortal^.X + poffs * conPortal^.dX + noffs * nx;
- iterator^.Y := conPortal^.Y + poffs * conPortal^.dY + noffs * ny;
-
- if not hasdxy and (not (conPortal^.dY.isNegative)) then
- begin
- iterator^.dY:= iterator^.dY + hwAbs(cGravity * (iterator^.Y - conPortal^.Y))
- end;
-
- // see if the space on the exit side actually is enough
-
- if not (isBullet or isCake) then
- begin
- // TestCollisionXwithXYShift requires a hwFloat for xShift
- ox.QWordValue := _1.QWordValue;
- ox.isNegative := not iterator^.dX.isNegative;
-
- sx := hwSign(iterator^.dX);
- sy := hwSign(iterator^.dY);
-
- if iterator^.Radius > 1 then
- iterator^.Radius := iterator^.Radius - 1;
-
- // check front
- isCollision := TestCollisionY(iterator, sy)
- or TestCollisionX(iterator, sx);
-
- if not isCollision then
- begin
- // check center area (with half the radius so that the
- // the square check won't check more pixels than we want to)
- iterator^.Radius := 1 + resetr div 2;
- rh := resetr div 4;
- isCollision := TestCollisionYwithXYShift(iterator, 0, -sy * rh, sy, false)
- or TestCollisionXwithXYShift(iterator, ox * rh, 0, sx, false);
- end;
-
- iterator^.Radius := resetr;
-
- if isCollision then
- begin
- // collision! oh crap! go back!
- iterator^.X := resetx;
- iterator^.Y := resety;
- iterator^.dX := resetdx;
- iterator^.dY := resetdy;
- continue;
- end;
- end;
-
- //
- // You're now officially portaled!
- //
-
- // Until loops are reliably broken
- if iscake then
- iterator^.PortalCounter:= 33
- else
- begin
- inc(iterator^.PortalCounter);
- iterator^.Active:= true;
- iterator^.State:= iterator^.State and (not gstHHHJump) or gstMoving;
- end;
-
- // is it worth adding an arcsin table? Just how often would we end up doing something like this?
- // SYNCED ANGLE UPDATE
- if iterator^.Kind = gtRCPlane then
- begin
- // recycling as temp vars
- resety.isNegative:= false;
- resety.QWordValue:= 4294967296 * 112;
- resetx.isNegative:= false;
- resetx.QWordValue:= 4294967296 * 35;
- resetdx.isNegative:= false;
- resetdx.QWordValue:= 4294967296 * 1152;
-
- resetdy:=hwAbs(iterator^.dX*4);
- resetdy:= resetdy + hwPow(resetdy,3)/_6 + _3 * hwPow(resetdy,5) / _40 + _5 * hwPow(resetdy,7) / resety + resetx * hwPow(resetdy,9) / resetdx;
- iterator^.Angle:= hwRound(resetdy*_2048 / _PI);
- if not iterator^.dY.isNegative then iterator^.Angle:= 2048-iterator^.Angle;
- if iterator^.dX.isNegative then iterator^.Angle:= 4096-iterator^.Angle;
- end
- // VISUAL USE OF ANGLE ONLY
- else if (CurAmmoGear <> nil) and (CurAmmoGear^.Kind = gtKamikaze) and (CurAmmoGear^.Hedgehog = iterator^.Hedgehog) then
- begin
- iterator^.Angle:= DxDy2AttackAngle(iterator^.dX, iterator^.dY);
- iterator^.Angle:= 2048-iterator^.Angle;
- if iterator^.dX.isNegative then iterator^.Angle:= 4096-iterator^.Angle;
- end;
-
- if (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil)
- and (iterator = CurrentHedgehog^.Gear)
- and (CurAmmoGear <> nil)
- and (CurAmmoGear^.Kind =gtRope) then
- CurAmmoGear^.PortalCounter:= 1;
-
- if not isbullet and (iterator^.State and gstInvisible = 0)
- and (iterator^.Kind <> gtFlake) then
- FollowGear := iterator;
-
- // store X/Y values of exit for net bullet trail
- if isbullet then
- begin
- iterator^.Elasticity:= iterator^.X;
- iterator^.Friction := iterator^.Y;
- end;
-
- if Gear^.Health > 1 then
- dec(Gear^.Health);
- end;
-end;
-
-
-
-procedure loadNewPortalBall(oldPortal: PGear; destroyGear: Boolean);
-var
- CurWeapon: PAmmo;
-begin
- if CurrentHedgehog <> nil then
- with CurrentHedgehog^ do
- begin
- CurWeapon:= GetCurAmmoEntry(CurrentHedgehog^);
- if (CurAmmoType = amPortalGun) then
- begin
- if not destroyGear then
- begin
- // switch color of ball to opposite of oldPortal
- if (oldPortal^.Tag and 2) = 0 then
- CurWeapon^.Pos:= 1
- else
- CurWeapon^.Pos:= 0;
- end;
-
- // make the ball visible
- CurWeapon^.Timer := 0;
- end
- end;
- if destroyGear then
- oldPortal^.Timer:= 0;
-end;
-
-procedure doStepMovingPortal_real(Gear: PGear);
-var
- x, y, tx, ty: LongInt;
- s: hwFloat;
-begin
- x := hwRound(Gear^.X);
- y := hwRound(Gear^.Y);
- tx := 0;
- ty := 0;
- // avoid compiler hints
-
- if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) and (Land[y, x] > 255) then
- begin
- Gear^.State := Gear^.State or gstCollision;
- Gear^.State := Gear^.State and (not gstMoving);
-
- if (Land[y, x] and lfBouncy <> 0)
- or (not CalcSlopeTangent(Gear, x, y, tx, ty, 255))
- or (DistanceI(tx,ty) < _12) then // reject shots at too irregular terrain
- begin
- loadNewPortalBall(Gear, true);
- EXIT;
- end;
-
- // making a normalized normal vector
- s := _1/DistanceI(tx,ty);
- Gear^.dX := s * ty;
- Gear^.dY := -s * tx;
-
- Gear^.DirAngle := DxDy2Angle(-Gear^.dY,Gear^.dX);
- if not Gear^.dX.isNegative then
- Gear^.DirAngle := 180-Gear^.DirAngle;
-
- if ((Gear^.LinkedGear = nil)
- or (hwRound(Distance(Gear^.X - Gear^.LinkedGear^.X,Gear^.Y-Gear^.LinkedGear^.Y)) >=Gear^.Radius*2)) then
- begin
- loadNewPortalBall(Gear, false);
- inc(Gear^.Tag);
- Gear^.doStep := @doStepPortal;
- end
- else
- loadNewPortalBall(Gear, true);
- end
-
- else if (y > cWaterLine)
- or (y < -max(LAND_WIDTH,4096))
- or (x > 2*max(LAND_WIDTH,4096))
- or (x < -max(LAND_WIDTH,4096)) then
- loadNewPortalBall(Gear, true);
-end;
-
-procedure doStepMovingPortal(Gear: PGear);
-begin
- doPortalColorSwitch();
- doStepPerPixel(Gear, @doStepMovingPortal_real, true);
- if (Gear^.Timer < 1)
- or (Gear^.Hedgehog^.Team <> CurrentHedgehog^.Team) then
- deleteGear(Gear);
-end;
-
-procedure doStepPortalShot(newPortal: PGear);
-var
- iterator: PGear;
- s: hwFloat;
- CurWeapon: PAmmo;
-begin
- s:= Distance (newPortal^.dX, newPortal^.dY);
-
- // Adds the hog speed (only that part in/directly against shot direction)
- // to the shot speed (which we triple previously btw)
- // (This is done my projecting the hog movement vector onto the shot movement vector and then adding the resulting length
- // to the scaler)
- s := (_2 * s + (newPortal^.dX * CurrentHedgehog^.Gear^.dX + newPortal^.dY * CurrentHedgehog^.Gear^.dY ) / s) / s;
- newPortal^.dX := newPortal^.dX * s;
- newPortal^.dY := newPortal^.dY * s;
-
- newPortal^.LinkedGear := nil;
-
- if CurrentHedgehog <> nil then
- with CurrentHedgehog^ do
- begin
- CurWeapon:= GetCurAmmoEntry(CurrentHedgehog^);
- // let's save the HH's dX's direction so we can decide where the "top" of the portal hole
- newPortal^.Elasticity.isNegative := CurrentHedgehog^.Gear^.dX.isNegative;
- // when doing a backjump the dx is the opposite of the facing direction
- if ((Gear^.State and gstHHHJump) <> 0) and (not cArtillery) then
- newPortal^.Elasticity.isNegative := not newPortal^.Elasticity.isNegative;
-
- // make portal gun look unloaded
- if (CurWeapon <> nil) and (CurAmmoType = amPortalGun) then
- CurWeapon^.Timer := CurWeapon^.Timer or 2;
-
- iterator := GearsList;
- while iterator <> nil do
- begin
- if (iterator^.Kind = gtPortal) then
- if (iterator <> newPortal) and (iterator^.Timer > 0) and (iterator^.Hedgehog = CurrentHedgehog) then
- begin
- if ((iterator^.Tag and 2) = (newPortal^.Tag and 2)) then
- begin
- iterator^.Timer:= 0;
- end
- else
- begin
- // link portals with each other
- newPortal^.LinkedGear := iterator;
- iterator^.LinkedGear := newPortal;
- iterator^.Health := newPortal^.Health;
- end;
- end;
- iterator^.PortalCounter:= 0;
- iterator := iterator^.NextGear
- end;
-
- if newPortal^.LinkedGear <> nil then
- begin
- // This jiggles gears, to ensure a portal connection just placed under a gear takes effect.
- iterator:= GearsList;
- while iterator <> nil do
- begin
- if not (iterator^.Kind in [gtPortal, gtAirAttack, gtKnife]) and ((iterator^.Hedgehog <> CurrentHedgehog)
- or ((iterator^.Message and gmAllStoppable) = 0)) then
- begin
- iterator^.Active:= true;
- if iterator^.dY.QWordValue = 0 then
- iterator^.dY.isNegative:= false;
- iterator^.State:= iterator^.State or gstMoving;
- DeleteCI(iterator);
- //inc(iterator^.dY.QWordValue,10);
- end;
- iterator:= iterator^.NextGear
- end
- end
- end;
- newPortal^.State := newPortal^.State and (not gstCollision);
- newPortal^.State := newPortal^.State or gstMoving;
- newPortal^.doStep := @doStepMovingPortal;
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepPiano(Gear: PGear);
-var
- r0, r1: LongInt;
- odY: hwFloat;
-begin
- AllInactive := false;
- if (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil) and
- ((CurrentHedgehog^.Gear^.Message and gmSlot) <> 0) then
- begin
- case CurrentHedgehog^.Gear^.MsgParam of
- 0: PlaySound(sndPiano0);
- 1: PlaySound(sndPiano1);
- 2: PlaySound(sndPiano2);
- 3: PlaySound(sndPiano3);
- 4: PlaySound(sndPiano4);
- 5: PlaySound(sndPiano5);
- 6: PlaySound(sndPiano6);
- 7: PlaySound(sndPiano7);
- else PlaySound(sndPiano8);
- end;
- AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtNote);
- CurrentHedgehog^.Gear^.MsgParam := 0;
- CurrentHedgehog^.Gear^.Message := CurrentHedgehog^.Gear^.Message and (not gmSlot);
- end;
-
- if (*((Gear^.Pos = 3) and ((GameFlags and gfSolidLand) <> 0)) or*) (Gear^.Pos = 5) then
- begin
- Gear^.dY := Gear^.dY + cGravity * 2;
- Gear^.Y := Gear^.Y + Gear^.dY;
- if CheckGearDrowning(Gear) then
- begin
- Gear^.Y:= Gear^.Y + _50;
- OnUsedAmmo(CurrentHedgehog^);
- if CurrentHedgehog^.Gear <> nil then
- begin
- // Drown the hedgehog. Could also just delete it, but hey, this gets a caption
- CurrentHedgehog^.Gear^.Active := true;
- CurrentHedgehog^.Gear^.X := Gear^.X;
- CurrentHedgehog^.Gear^.Y := int2hwFloat(cWaterLine+cVisibleWater)+_128;
- CurrentHedgehog^.Unplaced := false;
- if TagTurnTimeLeft = 0 then
- TagTurnTimeLeft:= TurnTimeLeft;
- TurnTimeLeft:= 0
- end;
- ResumeMusic
- end;
- exit
- end;
-
- odY:= Gear^.dY;
- doStepFallingGear(Gear);
-
- if (Gear^.State and gstDrowning) <> 0 then
- begin
- Gear^.Y:= Gear^.Y + _50;
- OnUsedAmmo(CurrentHedgehog^);
- if CurrentHedgehog^.Gear <> nil then
- begin
- // Drown the hedgehog. Could also just delete it, but hey, this gets a caption
- CurrentHedgehog^.Gear^.Active := true;
- CurrentHedgehog^.Gear^.X := Gear^.X;
- CurrentHedgehog^.Gear^.Y := int2hwFloat(cWaterLine+cVisibleWater)+_128;
- CurrentHedgehog^.Unplaced := false;
- if TagTurnTimeLeft = 0 then
- TagTurnTimeLeft:= TurnTimeLeft;
- TurnTimeLeft:= 0
- end;
- ResumeMusic
- end
- else if (Gear^.State and gstCollision) <> 0 then
- begin
- r0 := GetRandom(21);
- r1 := GetRandom(21);
- doMakeExplosion(hwRound(Gear^.X) - 30 - r0, hwRound(Gear^.Y) + 40, 40 + r1, Gear^.Hedgehog, 0);
- doMakeExplosion(hwRound(Gear^.X) + 30 + r1, hwRound(Gear^.Y) + 40, 40 + r0, Gear^.Hedgehog, 0);
- doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 80 + r0, Gear^.Hedgehog, EXPLAutoSound);
- for r0:= 0 to 4 do
- AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtNote);
- Gear^.dY := cGravity * 2 - odY;
- Gear^.Pos := Gear^.Pos + 1;
- end
- else
- Gear^.dY := Gear^.dY + cGravity * 2;
- // let it fall faster so itdoesn't take too long for the whole attack
-end;
-
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepSineGunShotWork(Gear: PGear);
-var
- x, y, rX, rY, t, tmp, initHealth: LongInt;
- oX, oY, ldX, ldY, sdX, sdY, sine, lx, ly, amp: hwFloat;
- justCollided: boolean;
-begin
- AllInactive := false;
- initHealth := Gear^.Health;
- lX := Gear^.X;
- lY := Gear^.Y;
- ldX := Gear^.dX;
- ldY := Gear^.dY;
- sdy := _0_5/Distance(Gear^.dX,Gear^.dY);
- ldX := ldX * sdy;
- ldY := ldY * sdy;
- sdY := hwAbs(ldX) + hwAbs(ldY);
- sdX := _1 - hwAbs(ldX/sdY);
- sdY := _1 - hwAbs(ldY/sdY);
- if (ldX.isNegative = ldY.isNegative) then
- sdY := -sdY;
-
- // initial angle depends on current GameTicks
- t := getRandom(4096);
-
-
- // used for a work-around detection of area that is within land array, but outside borders
- justCollided := false;
-
- repeat
- lX := lX + ldX;
- lY := lY + ldY;
- oX := Gear^.X;
- oY := Gear^.Y;
- rX := hwRound(oX);
- rY := hwRound(oY);
- tmp := t mod 4096;
- amp := _128 * (_1 - hwSqr(int2hwFloat(Gear^.Health)/initHealth));
- sine := amp * AngleSin(tmp mod 2048);
- sine.isNegative := (tmp < 2048);
- inc(t,Gear^.Health div 313);
- Gear^.X := lX + (sine * sdX);
- Gear^.Y := ly + (sine * sdY);
- Gear^.dX := Gear^.X - oX;
- Gear^.dY := Gear^.Y - oY;
-
- x := hwRound(Gear^.X);
- y := hwRound(Gear^.Y);
-
- // if borders are on, stop outside land array
- if hasBorder and (((x and LAND_WIDTH_MASK) <> 0) or ((y and LAND_HEIGHT_MASK) <> 0)) then
- begin
- Gear^.Damage := 0;
- Gear^.Health := 0;
- end
- else
- begin
- if (rY <= cWaterLine) or (y <= cWaterLine) then
- begin
- if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0)
- and (Land[y, x] <> 0) then
- begin
- if justCollided then
- begin
- Gear^.Damage := 0;
- Gear^.Health := 0;
- end
- else
- begin
- inc(Gear^.Damage,3);
- justCollided := true;
- end;
- end
- else
- justCollided := false;
-
- // kick nearby hogs, dig tunnel and add some fire
- // if at least 5 collisions occured
- if Gear^.Damage > 0 then
- begin
- DrawExplosion(rX,rY,Gear^.Radius);
-
- // kick nearby hogs
- AmmoShove(Gear, 35, 50);
-
- dec(Gear^.Health, Gear^.Damage);
- Gear^.Damage := 0;
-
- // add some fire to the tunnel
- if getRandom(6) = 0 then
- begin
- tmp:= GetRandom(2 * Gear^.Radius);
- AddGear(x - Gear^.Radius + tmp, y - GetRandom(Gear^.Radius + 1), gtFlame, gsttmpFlag, _0, _0, 0)
- end
- end;
-
- if random(100) = 0 then
- AddVisualGear(x, y, vgtSmokeTrace);
- end
- else dec(Gear^.Health, 5); // if underwater get additional damage
- end;
-
- dec(Gear^.Health);
-
- // decrease bullet size towards the end
- if (Gear^.Radius > 4) then
- begin
- if (Gear^.Health <= (initHealth div 3)) then
- dec(Gear^.Radius)
- end
- else if (Gear^.Radius > 3) then
- begin
- if (Gear^.Health <= (initHealth div 4)) then
- dec(Gear^.Radius)
- end
- else if (Gear^.Radius > 2) then begin
- if (Gear^.Health <= (initHealth div 5)) then
- dec(Gear^.Radius)
- end
- else if (Gear^.Radius > 1) then
- begin
- if (Gear^.Health <= (initHealth div 6)) then
- dec(Gear^.Radius)
- end;
-
- until (Gear^.Health <= 0);
-
- DeleteGear(Gear);
- AfterAttack;
-end;
-
-procedure doStepSineGunShot(Gear: PGear);
-var
- HHGear: PGear;
-begin
- PlaySound(sndSineGun);
-
- // push the shooting Hedgehog back
- HHGear := CurrentHedgehog^.Gear;
- Gear^.dX.isNegative := not Gear^.dX.isNegative;
- Gear^.dY.isNegative := not Gear^.dY.isNegative;
- HHGear^.dX := Gear^.dX;
- HHGear^.dY := Gear^.dY;
- AmmoShove(Gear, 0, 80);
- Gear^.dX.isNegative := not Gear^.dX.isNegative;
- Gear^.dY.isNegative := not Gear^.dY.isNegative;
-
- Gear^.doStep := @doStepSineGunShotWork;
- with mobileRecord do
- if (performRumble <> nil) and (not fastUntilLag) then
- performRumble(kSystemSoundID_Vibrate);
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepFlamethrowerWork(Gear: PGear);
-var
- HHGear, flame: PGear;
- rx, ry, speed: hwFloat;
- i, gX, gY: LongInt;
-begin
- AllInactive := false;
- HHGear := Gear^.Hedgehog^.Gear;
- HedgehogChAngle(HHGear);
- gX := hwRound(Gear^.X) + GetLaunchX(amBallgun, hwSign(HHGear^.dX), HHGear^.Angle);
- gY := hwRound(Gear^.Y) + GetLaunchY(amBallgun, HHGear^.Angle);
-
- if (GameTicks and $FF) = 0 then
- begin
- if (HHGear^.Message and gmRight) <> 0 then
- begin
- if HHGear^.dX.isNegative and (Gear^.Tag < 20) then
- inc(Gear^.Tag)
- else if Gear^.Tag > 5 then
- dec(Gear^.Tag);
- end
- else if (HHGear^.Message and gmLeft) <> 0 then
- begin
- if HHGear^.dX.isNegative and (Gear^.Tag > 5) then
- dec(Gear^.Tag)
- else if Gear^.Tag < 20 then
- inc(Gear^.Tag);
- end
- end;
-
- dec(Gear^.Timer);
- if Gear^.Timer = 0 then
- begin
- dec(Gear^.Health);
- if (Gear^.Health mod 5) = 0 then
- begin
- rx := rndSign(getRandomf * _0_1);
- ry := rndSign(getRandomf * _0_1);
- speed := _0_5 * (_10 / Gear^.Tag);
-
- flame:= AddGear(gx, gy, gtFlame, gstTmpFlag,
- SignAs(AngleSin(HHGear^.Angle) * speed, HHGear^.dX) + rx,
- AngleCos(HHGear^.Angle) * ( - speed) + ry, 0);
- flame^.CollisionMask:= lfNotCurrentMask;
-
- if (Gear^.Health mod 30) = 0 then
- begin
- flame:= AddGear(gx, gy, gtFlame, 0,
- SignAs(AngleSin(HHGear^.Angle) * speed, HHGear^.dX) + rx,
- AngleCos(HHGear^.Angle) * ( - speed) + ry, 0);
- flame^.CollisionMask:= lfNotCurrentMask;
- end
- end;
- Gear^.Timer:= Gear^.Tag
- end;
-
- if (Gear^.Health = 0) or ((HHGear^.State and gstHHDriven) = 0) then
- begin
- DeleteGear(Gear);
- AfterAttack
- end
- else
- begin
- i:= Gear^.Health div 5;
- if (i <> Gear^.Damage) and ((GameTicks and $3F) = 0) then
- begin
- Gear^.Damage:= i;
- FreeTexture(Gear^.Tex);
- Gear^.Tex := RenderStringTex(trmsg[sidFuel] + ': ' + inttostr(i) +
- '%', cWhiteColor, fntSmall)
- end
- end
-end;
-
-procedure doStepFlamethrower(Gear: PGear);
-var
- HHGear: PGear;
-begin
- HHGear := Gear^.Hedgehog^.Gear;
- HHGear^.Message := HHGear^.Message and (not (gmUp or gmDown or gmLeft or gmRight));
- HHGear^.State := HHGear^.State or gstNotKickable;
- Gear^.doStep := @doStepFlamethrowerWork
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepLandGunWork(Gear: PGear);
-var
- HHGear, land: PGear;
- rx, ry, speed: hwFloat;
- i, gX, gY: LongInt;
-begin
- AllInactive := false;
- HHGear := Gear^.Hedgehog^.Gear;
- HedgehogChAngle(HHGear);
- gX := hwRound(Gear^.X) + GetLaunchX(amBallgun, hwSign(HHGear^.dX), HHGear^.Angle);
- gY := hwRound(Gear^.Y) + GetLaunchY(amBallgun, HHGear^.Angle);
-
- if (GameTicks and $FF) = 0 then
- begin
- if (HHGear^.Message and gmRight) <> 0 then
- begin
- if HHGear^.dX.isNegative and (Gear^.Tag < 20) then
- inc(Gear^.Tag)
- else if Gear^.Tag > 5 then
- dec(Gear^.Tag);
- end
- else if (HHGear^.Message and gmLeft) <> 0 then
- begin
- if HHGear^.dX.isNegative and (Gear^.Tag > 5) then
- dec(Gear^.Tag)
- else if Gear^.Tag < 20 then
- inc(Gear^.Tag);
- end
- end;
-
- dec(Gear^.Timer);
- if Gear^.Timer = 0 then
- begin
- dec(Gear^.Health);
-
- rx := rndSign(getRandomf * _0_1);
- ry := rndSign(getRandomf * _0_1);
- speed := (_3 / Gear^.Tag);
-
- land:= AddGear(gx, gy, gtFlake, gstTmpFlag,
- SignAs(AngleSin(HHGear^.Angle) * speed, HHGear^.dX) + rx,
- AngleCos(HHGear^.Angle) * ( - speed) + ry, 0);
- land^.CollisionMask:= lfNotCurrentMask;
-
- Gear^.Timer:= Gear^.Tag
- end;
-
- if (Gear^.Health = 0) or ((HHGear^.State and gstHHDriven) = 0) or ((HHGear^.Message and gmAttack) <> 0) then
- begin
- HHGear^.Message:= HHGear^.Message and (not gmAttack);
- DeleteGear(Gear);
- AfterAttack
- end
- else
- begin
- i:= Gear^.Health div 10;
- if (i <> Gear^.Damage) and ((GameTicks and $3F) = 0) then
- begin
- Gear^.Damage:= i;
- FreeTexture(Gear^.Tex);
- Gear^.Tex := RenderStringTex(trmsg[sidFuel] + ': ' + inttostr(i) +
- '%', cWhiteColor, fntSmall)
- end
- end
-end;
-
-procedure doStepLandGun(Gear: PGear);
-var
- HHGear: PGear;
-begin
- HHGear := Gear^.Hedgehog^.Gear;
- HHGear^.Message := HHGear^.Message and (not (gmUp or gmDown or gmLeft or gmRight or gmAttack));
- HHGear^.State := HHGear^.State or gstNotKickable;
- Gear^.doStep := @doStepLandGunWork
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepPoisonCloud(Gear: PGear);
-begin
- if Gear^.Timer = 0 then
- begin
- DeleteGear(Gear);
- exit
- end;
- dec(Gear^.Timer);
- Gear^.X:= Gear^.X + Gear^.dX;
- Gear^.Y:= Gear^.Y + Gear^.dY;
- Gear^.dX := Gear^.dX + cWindSpeed / 4;
- Gear^.dY := Gear^.dY + cGravity / 100;
- if (GameTicks and $FF) = 0 then
- doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 20, Gear^.Hedgehog, EXPLDontDraw or EXPLNoGfx or EXPLNoDamage or EXPLDoNotTouchAny or EXPLPoisoned);
- AllInactive:= false;
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepHammer(Gear: PGear);
-var HHGear, tmp, tmp2: PGear;
- t: PGearArray;
- i: LongInt;
-begin
-HHGear:= Gear^.Hedgehog^.Gear;
-HHGear^.State:= HHGear^.State or gstNoDamage;
-DeleteCI(HHGear);
-
-t:= CheckGearsCollision(Gear);
-
-for i:= 5 downto 0 do
- AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12, vgtDust);
-
-i:= t^.Count;
-while i > 0 do
- begin
- dec(i);
- tmp:= t^.ar[i];
- if (tmp^.State and gstNoDamage) = 0 then
- if (tmp^.Kind = gtHedgehog) or (tmp^.Kind = gtMine) or (tmp^.Kind = gtExplosives) then
- begin
- //tmp^.State:= tmp^.State or gstFlatened;
- if not tmp^.Invulnerable then
- ApplyDamage(tmp, CurrentHedgehog, tmp^.Health div 3, dsUnknown);
- //DrawTunnel(tmp^.X, tmp^.Y - _1, _0, _0_5, cHHRadius * 6, cHHRadius * 3);
- tmp2:= AddGear(hwRound(tmp^.X), hwRound(tmp^.Y), gtHammerHit, 0, _0, _0, 0);
- tmp2^.LinkedGear:= tmp;
- SetAllToActive
- end
- else
- begin
- end
- end;
-
-HHGear^.State:= HHGear^.State and (not gstNoDamage);
-Gear^.Timer:= 250;
-Gear^.doStep:= @doStepIdle
-end;
-
-procedure doStepHammerHitWork(Gear: PGear);
-var
- i, j, ei: LongInt;
- HitGear: PGear;
-begin
- AllInactive := false;
- HitGear := Gear^.LinkedGear;
- dec(Gear^.Timer);
- if (HitGear = nil) or (Gear^.Timer = 0) or ((Gear^.Message and gmDestroy) <> 0) then
- begin
- DeleteGear(Gear);
- exit
- end;
-
- if (Gear^.Timer mod 5) = 0 then
- begin
- AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12, vgtDust);
-
- i := hwRound(Gear^.X) - HitGear^.Radius + 2;
- ei := hwRound(Gear^.X) + HitGear^.Radius - 2;
- for j := 1 to 4 do DrawExplosion(i - GetRandom(5), hwRound(Gear^.Y) + 6*j, 3);
- for j := 1 to 4 do DrawExplosion(ei + LongInt(GetRandom(5)), hwRound(Gear^.Y) + 6*j, 3);
- while i <= ei do
- begin
- for j := 1 to 11 do DrawExplosion(i, hwRound(Gear^.Y) + 3*j, 3);
- inc(i, 1)
- end;
-
- if CheckLandValue(hwRound(Gear^.X + Gear^.dX + SignAs(_6,Gear^.dX)), hwRound(Gear^.Y + _1_9)
- , lfIndestructible) then
- begin
- //Gear^.X := Gear^.X + Gear^.dX;
- Gear^.Y := Gear^.Y + _1_9
- end;
- end;
- if TestCollisionYwithGear(Gear, 1) <> 0 then
- begin
- Gear^.dY := _0;
- SetLittle(HitGear^.dX);
- HitGear^.dY := _0;
- end
- else
- begin
- //Gear^.dY := Gear^.dY + cGravity;
- //Gear^.Y := Gear^.Y + Gear^.dY;
- if hwRound(Gear^.Y) > cWaterLine then
- Gear^.Timer := 1
- end;
-
- //Gear^.X := Gear^.X + HitGear^.dX;
- HitGear^.X := Gear^.X;
- HitGear^.Y := Gear^.Y;
- SetLittle(HitGear^.dY);
- HitGear^.Active:= true;
-end;
-
-procedure doStepHammerHit(Gear: PGear);
-var
- i, y: LongInt;
- ar: TRangeArray;
- HHGear: PGear;
-begin
- i := 0;
- HHGear := Gear^.Hedgehog^.Gear;
-
- y := hwRound(Gear^.Y) - cHHRadius * 2;
- while y < hwRound(Gear^.Y) do
- begin
- ar[i].Left := hwRound(Gear^.X) - Gear^.Radius - LongInt(GetRandom(2));
- ar[i].Right := hwRound(Gear^.X) + Gear^.Radius + LongInt(GetRandom(2));
- inc(y, 2);
- inc(i)
- end;
-
- DrawHLinesExplosions(@ar, 3, hwRound(Gear^.Y) - cHHRadius * 2, 2, Pred(i));
- Gear^.dY := HHGear^.dY;
- DeleteCI(HHGear);
-
- doStepHammerHitWork(Gear);
- Gear^.doStep := @doStepHammerHitWork
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepResurrectorWork(Gear: PGear);
-var
- graves: PGearArrayS;
- resgear: PGear;
- hh: PHedgehog;
- i: LongInt;
-begin
- if (TurnTimeLeft > 0) then
- dec(TurnTimeLeft);
-
- AllInactive := false;
- hh := Gear^.Hedgehog;
-
- // no, you can't do that here
- {DrawCentered(hwRound(hh^.Gear^.X) + WorldDx, hwRound(hh^.Gear^.Y) + WorldDy -
- cHHRadius - 14 - hh^.HealthTagTex^.h, hh^.HealthTagTex);
- }
- (*DrawCircle(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Radius, 1.5, 0, 0, $FF,
- $FF);*)
-
- if ((Gear^.Message and gmUp) <> 0) then
- begin
- if (GameTicks and $F) <> 0 then
- exit;
- end
- else if (GameTicks and $1FF) <> 0 then
- exit;
-
- if Gear^.Power < 45 then
- begin
- inc(Gear^.Power);
- if TestCollisionYwithGear(hh^.Gear, -1) = 0 then
- hh^.Gear^.Y := hh^.Gear^.Y - _1;
- end;
-
- graves := GearsNear(Gear^.X, Gear^.Y, gtGrave, Gear^.Radius);
-
- if graves.size = 0 then
- begin
- StopSoundChan(Gear^.SoundChannel);
- Gear^.Timer := 250;
- Gear^.doStep := @doStepIdle;
- exit;
- end;
-
- if ((Gear^.Message and gmAttack) <> 0) and (hh^.Gear^.Health > 0) and (TurnTimeLeft > 0) then
- begin
- if LongInt(graves.size) <= Gear^.Tag then Gear^.Tag:= 0;
- dec(hh^.Gear^.Health);
- if (hh^.Gear^.Health = 0) and (hh^.Gear^.Damage = 0) then
- hh^.Gear^.Damage:= 1;
- RenderHealth(hh^);
- RecountTeamHealth(hh^.Team);
- inc(graves.ar^[Gear^.Tag]^.Health);
- inc(Gear^.Tag)
-{-for i:= 0 to High(graves) do begin
- if hh^.Gear^.Health > 0 then begin
- dec(hh^.Gear^.Health);
- inc(graves[i]^.Health);
- end;
- end; -}
- end
- else
- begin
- // now really resurrect the hogs with the hp saved in the graves
- for i:= 0 to graves.size - 1 do
- if graves.ar^[i]^.Health > 0 then
- begin
- resgear := AddGear(hwRound(graves.ar^[i]^.X), hwRound(graves.ar^[i]^.Y), gtHedgehog, gstWait, _0, _0, 0);
- resgear^.Hedgehog := graves.ar^[i]^.Hedgehog;
- resgear^.Health := graves.ar^[i]^.Health;
- PHedgehog(graves.ar^[i]^.Hedgehog)^.Gear := resgear;
- graves.ar^[i]^.Message:= graves.ar^[i]^.Message or gmDestroy;
- graves.ar^[i]^.Active:= true;
- RenderHealth(resgear^.Hedgehog^);
- RecountTeamHealth(resgear^.Hedgehog^.Team);
- resgear^.Hedgehog^.Effects[heResurrected]:= 1;
- // only make hat-less hedgehogs look like zombies, preserve existing hats
-
- if resgear^.Hedgehog^.Hat = 'NoHat' then
- LoadHedgehogHat(resgear^.Hedgehog^, 'Reserved/Zombie');
- end;
-
- hh^.Gear^.dY := _0;
- hh^.Gear^.dX := _0;
- doStepHedgehogMoving(hh^.Gear);
- StopSoundChan(Gear^.SoundChannel);
- Gear^.Timer := 250;
- Gear^.doStep := @doStepIdle;
- end
- //if hh^.Gear^.Health = 0 then doStepHedgehogFree(hh^.Gear);
-end;
-
-procedure doStepResurrector(Gear: PGear);
-var
- graves: PGearArrayS;
- hh: PHedgehog;
- i: LongInt;
-begin
- AllInactive := false;
- graves := GearsNear(Gear^.X, Gear^.Y, gtGrave, Gear^.Radius);
-
- if graves.size > 0 then
- begin
- hh := Gear^.Hedgehog;
- for i:= 0 to graves.size - 1 do
- begin
- PHedgehog(graves.ar^[i]^.Hedgehog)^.Gear := nil;
- graves.ar^[i]^.Health := 0;
- end;
- Gear^.doStep := @doStepResurrectorWork;
- if ((Gear^.Message and gmAttack) <> 0) and (hh^.Gear^.Health > 0) and (TurnTimeLeft > 0) then
- begin
- if LongInt(graves.size) <= Gear^.Tag then Gear^.Tag:= 0;
- dec(hh^.Gear^.Health);
- if (hh^.Gear^.Health = 0) and (hh^.Gear^.Damage = 0) then
- hh^.Gear^.Damage:= 1;
- RenderHealth(hh^);
- RecountTeamHealth(hh^.Team);
- inc(graves.ar^[Gear^.Tag]^.Health);
- inc(Gear^.Tag)
- end
- end
- else
- begin
- StopSoundChan(Gear^.SoundChannel);
- Gear^.Timer := 250;
- Gear^.doStep := @doStepIdle;
- end
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepNapalmBomb(Gear: PGear);
-var
- i, gX, gY: LongInt;
- dX, dY: hwFloat;
-begin
- AllInactive := false;
- doStepFallingGear(Gear);
- if (Gear^.Timer > 0) and ((Gear^.State and gstCollision) <> 0) then
- begin
- doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 10, Gear^.Hedgehog, EXPLAutoSound);
- gX := hwRound(Gear^.X);
- gY := hwRound(Gear^.Y);
- for i:= 0 to 10 do
- begin
- dX := AngleCos(i * 2) * ((_0_1*(i div 5))) * (GetRandomf + _1);
- dY := AngleSin(i * 8) * _0_5 * (GetRandomf + _1);
- AddGear(gX, gY, gtFlame, 0, dX, dY, 0);
- AddGear(gX, gY, gtFlame, 0, dX, -dY, 0);
- AddGear(gX, gY, gtFlame, 0, -dX, dY, 0);
- AddGear(gX, gY, gtFlame, 0, -dX, -dY, 0);
- end;
- DeleteGear(Gear);
- exit
- end;
- if (Gear^.Timer = 0) then
- begin
- doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 10, Gear^.Hedgehog, EXPLAutoSound);
- for i:= -19 to 19 do
- FollowGear := AddGear(hwRound(Gear^.X) + i div 3, hwRound(Gear^.Y), gtFlame, 0, _0_001 * i, _0, 0);
- DeleteGear(Gear);
- exit
- end;
- if (GameTicks and $3F) = 0 then
- AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace);
- dec(Gear^.Timer)
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepStructure(Gear: PGear);
-var
- x, y: LongInt;
- HH: PHedgehog;
- t: PGear;
-begin
- HH:= Gear^.Hedgehog;
-
- if (Gear^.State and gstMoving) <> 0 then
- begin
- AddGearCI(Gear);
- Gear^.dX:= _0;
- Gear^.dY:= _0;
- Gear^.State:= Gear^.State and (not gstMoving);
- end;
-
- dec(Gear^.Health, Gear^.Damage);
- Gear^.Damage:= 0;
-
- if Gear^.Pos = 1 then
- begin
- AddGearCI(Gear);
- AfterAttack;
- if Gear = CurAmmoGear then
- CurAmmoGear:= nil;
- if HH^.Gear <> nil then
- HideHog(HH);
- Gear^.Pos:= 2
- end;
-
- if Gear^.Pos = 2 then
- begin
- if ((GameTicks mod 100) = 0) and (Gear^.Timer < 1000) then
- begin
- if (Gear^.Timer mod 10) = 0 then
- begin
- DeleteCI(Gear);
- Gear^.Y:= Gear^.Y - _0_5;
- AddGearCI(Gear);
- end;
- inc(Gear^.Timer);
- end;
- if Gear^.Tag <= TotalRounds then
- Gear^.Pos:= 3;
- end;
-
- if Gear^.Pos = 3 then
- if Gear^.Timer < 1000 then
- begin
- if (Gear^.Timer mod 10) = 0 then
- begin
- DeleteCI(Gear);
- Gear^.Y:= Gear^.Y - _0_5;
- AddGearCI(Gear);
- end;
- inc(Gear^.Timer);
- end
- else
- begin
- if HH^.GearHidden <> nil then
- RestoreHog(HH);
- Gear^.Pos:= 4;
- end;
-
- if Gear^.Pos = 4 then
- if ((GameTicks mod 1000) = 0) and ((GameFlags and gfInvulnerable) = 0) then
- begin
- t:= GearsList;
- while t <> nil do
- begin
- if (t^.Kind = gtHedgehog) and (t^.Hedgehog^.Team^.Clan = HH^.Team^.Clan) then
- t^.Invulnerable:= true;
- t:= t^.NextGear;
- end;
- end;
-
- if Gear^.Health <= 0 then
- begin
- if HH^.GearHidden <> nil then
- RestoreHog(HH);
-
- x := hwRound(Gear^.X);
- y := hwRound(Gear^.Y);
-
- DeleteCI(Gear);
- DeleteGear(Gear);
-
- doMakeExplosion(x, y, 50, CurrentHedgehog, EXPLAutoSound);
- end;
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-(*
- TARDIS needs
- Warp in. Pos = 1
- Pause. Pos = 2
- Hide gear (TARDIS hedgehog was nil)
- Warp out. Pos = 3
- ... idle active for some time period ... Pos = 4
- Warp in. Pos = 1
- Pause. Pos = 2
- Restore gear (TARDIS hedgehog was not nil)
- Warp out. Pos = 3
-*)
-
-procedure doStepTardisWarp(Gear: PGear);
-var HH: PHedgehog;
- i,j,cnt: LongWord;
-begin
-HH:= Gear^.Hedgehog;
-if Gear^.Pos = 2 then
- begin
- StopSoundChan(Gear^.SoundChannel);
- if (Gear^.Timer = 0) then
- begin
- if (HH^.Gear <> nil) and (HH^.Gear^.State and gstInvisible = 0) then
- begin
- AfterAttack;
- if Gear = CurAmmoGear then CurAmmoGear := nil;
- if (HH^.Gear^.Damage = 0) and (HH^.Gear^.Health > 0) and
- ((Gear^.State and (gstMoving or gstHHDeath or gstHHGone)) = 0) then
- HideHog(HH)
- end
- //else if (HH^.Gear <> nil) and (HH^.Gear^.State and gstInvisible <> 0) then
- else if (HH^.GearHidden <> nil) then// and (HH^.Gear^.State and gstInvisible <> 0) then
- RestoreHog(HH)
- end;
-
- inc(Gear^.Timer);
- if (Gear^.Timer > 2000) and ((GameTicks mod 2000) = 1000) then
- begin
- Gear^.SoundChannel := LoopSound(sndTardis);
- Gear^.Pos:= 3
- end
- end;
-
-if (Gear^.Pos = 1) and (GameTicks and $1F = 0) and (Gear^.Power < 255) then
- begin
- inc(Gear^.Power);
- if (Gear^.Power = 172) and (HH^.Gear <> nil) and
- (HH^.Gear^.Damage = 0) and (HH^.Gear^.Health > 0) and
- ((HH^.Gear^.State and (gstMoving or gstHHDeath or gstHHGone)) = 0) then
- with HH^.Gear^ do
- begin
- State:= State or gstAnimation;
- Tag:= 2;
- Timer:= 0;
- Pos:= 0
- end
- end;
-if (Gear^.Pos = 3) and (GameTicks and $1F = 0) and (Gear^.Power > 0) then
- dec(Gear^.Power);
-if (Gear^.Pos = 1) and (Gear^.Power = 255) and ((GameTicks mod 2000) = 1000) then
- Gear^.Pos:= 2;
-if (Gear^.Pos = 3) and (Gear^.Power = 0) then
- begin
- StopSoundChan(Gear^.SoundChannel);
- if HH^.GearHidden = nil then
- begin
- DeleteGear(Gear);
- exit
- end;
- Gear^.Pos:= 4;
- // This condition might need tweaking
- Gear^.Timer:= GetRandom(cHedgehogTurnTime*TeamsCount)+cHedgehogTurnTime
- end;
-
-if (Gear^.Pos = 4) then
- begin
- cnt:= 0;
- for j:= 0 to Pred(HH^.Team^.Clan^.TeamsNumber) do
- for i:= 0 to Pred(HH^.Team^.Clan^.Teams[j]^.HedgehogsNumber) do
- if (HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear <> nil)
- and ((HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear^.State and gstDrowning) = 0)
- and (HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear^.Health > HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear^.Damage) then
- inc(cnt);
- if (cnt = 0) or SuddenDeathDmg or (Gear^.Timer = 0) then
- begin
- if HH^.GearHidden <> nil then
- FindPlace(HH^.GearHidden, false, 0, LAND_WIDTH,true);
-
- if HH^.GearHidden <> nil then
- begin
- Gear^.X:= HH^.GearHidden^.X;
- Gear^.Y:= HH^.GearHidden^.Y;
- end;
- Gear^.Timer:= 0;
-
- if (HH^.GearHidden <> nil) and (cnt = 0) then // do an emergency jump back in this case. the team needs you!
- begin
- AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtExplosion);
- Gear^.Pos:= 2;
- Gear^.Power:= 255;
- end
- else begin
- Gear^.SoundChannel := LoopSound(sndTardis);
- Gear^.Pos:= 1;
- Gear^.Power:= 0;
- end
- end
- else if (CurrentHedgehog^.Team^.Clan = Gear^.Hedgehog^.Team^.Clan) then dec(Gear^.Timer)
- end;
-
-end;
-
-procedure doStepTardis(Gear: PGear);
-var i,j,cnt: LongWord;
- HH: PHedgehog;
-begin
-(*
- Conditions for not activating.
- 1. Hog is last of his clan
- 2. Sudden Death is in play
- 3. Hog is a king
-*)
- HH:= Gear^.Hedgehog;
- if HH^.Gear <> nil then
- if (HH^.Gear = nil) or (HH^.King) or (SuddenDeathDmg) then
- begin
- if HH^.Gear <> nil then
- begin
- HH^.Gear^.Message := HH^.Gear^.Message and (not gmAttack);
- HH^.Gear^.State:= HH^.Gear^.State and (not gstAttacking);
- end;
- PlaySound(sndDenied);
- DeleteGear(gear);
- exit
- end;
- cnt:= 0;
- for j:= 0 to Pred(HH^.Team^.Clan^.TeamsNumber) do
- for i:= 0 to Pred(HH^.Team^.Clan^.Teams[j]^.HedgehogsNumber) do
- if (HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear <> nil)
- and ((HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear^.State and gstDrowning) = 0)
- and (HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear^.Health > HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear^.Damage) then
- inc(cnt);
- if cnt < 2 then
- begin
- if HH^.Gear <> nil then
- begin
- HH^.Gear^.Message := HH^.Gear^.Message and (not gmAttack);
- HH^.Gear^.State:= HH^.Gear^.State and (not gstAttacking);
- end;
- PlaySound(sndDenied);
- DeleteGear(gear);
- exit
- end;
- Gear^.SoundChannel := LoopSound(sndTardis);
- Gear^.doStep:= @doStepTardisWarp
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-
-(*
-WIP. The ice gun will have the following effects. It has been proposed by sheepluva that it take the appearance of a large freezer
-spewing ice cubes. The cubes will be visual gears only. The scatter from them and the impact snow dust should help hide imprecisions in things like the GearsNear effect.
-For now we assume a "ray" like a deagle projected out from the gun.
-All these effects assume the ray's angle is not changed and that the target type was unchanged over a number of ticks. This is a simplifying assumption for "gun was applying freezing effect to the same target".
- * When fired at water a layer of ice textured land is added above the water.
- * When fired at non-ice land (land and lfLandMask and not lfIce) the land is overlaid with a thin layer of ice textured land around that point (say, 1 or 2px into land, 1px above). For attractiveness, a slope would probably be needed.
- * When fired at a hog (land and $00FF <> 0), while the hog is targetted, the hog's state is set to frozen. As long as the gun is on the hog, a frozen hog sprite creeps up from the feet to the head. If the effect is interrupted before reaching the top, the freezing state is cleared.
-A frozen hog will animate differently. To be decided, but possibly in a similar fashion to a grave when it comes to explosions. The hog might (possibly) not be damaged by explosions. This might make freezing potentially useful for friendlies in a bad position. It might be better to allow damage though.
-A frozen hog stays frozen for a certain number of turns. Each turn the frozen overlay becomes fainter, until it fades and the hog animates normally again.
-*)
-
-
-procedure updateFuel(Gear: PGear);
-var
- t:LongInt;
-begin
- t:= Gear^.Health div 10;
- if (t <> Gear^.Damage) and ((GameTicks and $3F) = 0) then
- begin
- Gear^.Damage:= t;
- FreeTexture(Gear^.Tex);
- Gear^.Tex := RenderStringTex(trmsg[sidFuel] + ': ' + inttostr(t) +
- '%', cWhiteColor, fntSmall)
- end;
- if Gear^.Message and (gmUp or gmDown) <> 0 then
- begin
- StopSoundChan(Gear^.SoundChannel);
- Gear^.SoundChannel:= -1;
- if GameTicks mod 40 = 0 then dec(Gear^.Health)
- end
- else
- begin
- if Gear^.SoundChannel = -1 then
- Gear^.SoundChannel := LoopSound(sndIceBeam);
- if GameTicks mod 10 = 0 then dec(Gear^.Health)
- end
-end;
-
-
-procedure updateTarget(Gear:PGear; newX, newY:HWFloat);
-// var
-// iter:PGear;
-begin
- with Gear^ do
- begin
- dX:= newX;
- dY:= newY;
- Pos:= 0;
- Target.X:= NoPointX;
- LastDamage:= nil;
- X:= Hedgehog^.Gear^.X;
- Y:= Hedgehog^.Gear^.Y;
- end;
-end;
-
-procedure doStepIceGun(Gear: PGear);
-const iceWaitCollision = 0;
-const iceCollideWithGround = 1;
-//const iceWaitNextTarget:Longint = 2;
-//const iceCollideWithHog:Longint = 4;
-const iceCollideWithWater = 5;
-//const waterFreezingTime:Longint = 500;
-const groundFreezingTime = 1000;
-const iceRadius = 32;
-const iceHeight = 40;
-var
- HHGear, iter: PGear;
- landRect: TSDL_Rect;
- ndX, ndY: hwFloat;
- i, t, gX, gY: LongInt;
- hogs: PGearArrayS;
- vg: PVisualGear;
-begin
- HHGear := Gear^.Hedgehog^.Gear;
- if (Gear^.Message and gmAttack <> 0) or (Gear^.Health = 0) or (HHGear = nil) or (HHGear^.Damage <> 0) or (HHGear^.dX.QWordValue > 4294967) then
- begin
- StopSoundChan(Gear^.SoundChannel);
- DeleteGear(Gear);
- AfterAttack;
- exit
- end;
- updateFuel(Gear);
-
- with Gear^ do
- begin
- HedgehogChAngle(HHGear);
- ndX:= SignAs(AngleSin(HHGear^.Angle), HHGear^.dX) * _4;
- ndY:= -AngleCos(HHGear^.Angle) * _4;
- if (ndX <> dX) or (ndY <> dY) or
- ((Target.X <> NoPointX) and (Target.X and LAND_WIDTH_MASK = 0) and
- (Target.Y and LAND_HEIGHT_MASK = 0) and ((Land[Target.Y, Target.X] = 0))) then
- begin
- updateTarget(Gear, ndX, ndY);
- Timer := iceWaitCollision;
- end
- else
- begin
- X:= X + dX;
- Y:= Y + dY;
- gX:= hwRound(X);
- gY:= hwRound(Y);
- if Target.X = NoPointX then t:= hwRound(hwSqr(X-HHGear^.X)+hwSqr(Y-HHGear^.Y));
-
- if Target.X <> NoPointX then
- begin
- CheckCollision(Gear);
- if (State and gstCollision) <> 0 then
- begin
- if Timer = iceWaitCollision then
- begin
- Timer := iceCollideWithGround;
- Power := GameTicks;
- end
- end
- else if (target.y >= cWaterLine) then
- begin
- if Timer = iceWaitCollision then
- begin
- Timer := iceCollideWithWater;
- Power := GameTicks;
- end;
- end;
-
- if (abs(gX-Target.X) < 2) and (abs(gY-Target.Y) < 2) then
- begin
- X:= HHGear^.X;
- Y:= HHGear^.Y
- end;
-
- if (Timer = iceCollideWithGround) and ((GameTicks - Power) > groundFreezingTime) then
- begin
- FillRoundInLand(target.x, target.y, iceRadius, icePixel);
- landRect.x := min(max(target.x - iceRadius, 0), LAND_WIDTH - 1);
- landRect.y := min(max(target.y - iceRadius, 0), LAND_HEIGHT - 1);
- landRect.w := min(2*iceRadius, LAND_WIDTH - landRect.x - 1);
- landRect.h := min(2*iceRadius, LAND_HEIGHT - landRect.y - 1);
- UpdateLandTexture(landRect.x, landRect.w, landRect.y, landRect.h, true);
-
- // Freeze nearby mines/explosives/cases too
- iter := GearsList;
- while iter <> nil do
- begin
- if (iter^.State and gstFrozen = 0) and
- ((iter^.Kind = gtExplosives) or (iter^.Kind = gtCase) or (iter^.Kind = gtMine)) and
- (abs(iter^.X.Round-target.x)+abs(iter^.Y.Round-target.y)+2<2*iceRadius) and (Distance(iter^.X-int2hwFloat(target.x),iter^.Y-int2hwFloat(target.y))<int2hwFloat(iceRadius*2)) then
- begin
- for t:= 0 to 5 do
- begin
- vg:= AddVisualGear(hwRound(iter^.X)+random(4)-8, hwRound(iter^.Y)+random(8), vgtDust, 1);
- if vg <> nil then
- begin
- i:= random(100) + 155;
- vg^.Tint:= (i shl 24) or (i shl 16) or ($FF shl 8) or (random(200) + 55);
- vg^.Angle:= random(360);
- vg^.dx:= 0.001 * random(80);
- vg^.dy:= 0.001 * random(80)
- end
- end;
- PlaySound(sndHogFreeze);
- if iter^.Kind = gtMine then // dud mine block
- begin
- iter^.State:= iter^.State or gstFrozen;
- vg:= AddVisualGear(hwRound(iter^.X) - 4 + Random(8), hwRound(iter^.Y) - 4 - Random(4), vgtSmoke);
- if vg <> nil then
- vg^.Scale:= 0.5;
- PlaySound(sndVaporize);
- iter^.Health := 0;
- iter^.Damage := 0;
- iter^.State := iter^.State and (not gstAttacking)
- end
- else if iter^.Kind = gtCase then
- begin
- DeleteCI(iter);
- iter^.State:= iter^.State or gstFrozen;
- AddGearCI(iter)
- end
- else // gtExplosives
- begin
- iter^.State:= iter^.State or gstFrozen;
- iter^.Health:= iter^.Health + cBarrelHealth
- end
- end;
- iter:= iter^.NextGear
- end;
-
- // FillRoundInLandWithIce(Target.X, Target.Y, iceRadius);
- SetAllHHToActive;
- Timer := iceWaitCollision;
- end;
-
- if (Timer = iceCollideWithWater) and ((GameTicks - Power) > groundFreezingTime) then
- begin
- PlaySound(sndHogFreeze);
- DrawIceBreak(Target.X, cWaterLine - iceHeight, iceRadius, iceHeight);
- SetAllHHToActive;
- Timer := iceWaitCollision;
- end;
-(*
- Any ideas for something that would look good here?
- if (Target.X <> NoPointX) and ((Timer = iceCollideWithGround) or (Timer = iceCollideWithWater)) and (GameTicks mod max((groundFreezingTime-((GameTicks - Power)*2)),2) = 0) then //and CheckLandValue(Target.X, Target.Y, lfIce) then
- begin
- vg:= AddVisualGear(Target.X+random(20)-10, Target.Y+random(40)-10, vgtDust, 1);
- if vg <> nil then
- begin
- i:= random(100) + 155;
- vg^.Tint:= IceColor or $FF;
- vg^.Angle:= random(360);
- vg^.dx:= 0.001 * random(80);
- vg^.dy:= 0.001 * random(80)
- end
- end;
-*)
-
-// freeze nearby hogs
- hogs := GearsNear(int2hwFloat(Target.X), int2hwFloat(Target.Y), gtHedgehog, Gear^.Radius*2);
- if hogs.size > 0 then
- for i:= 0 to hogs.size - 1 do
- if hogs.ar^[i] <> HHGear then
- if GameTicks mod 5 = 0 then
- begin
- hogs.ar^[i]^.Active:= true;
- if hogs.ar^[i]^.Hedgehog^.Effects[heFrozen] < 256 then
- hogs.ar^[i]^.Hedgehog^.Effects[heFrozen] := hogs.ar^[i]^.Hedgehog^.Effects[heFrozen] + 1
- else if hogs.ar^[i]^.Hedgehog^.Effects[heFrozen] = 256 then
- begin
- hogs.ar^[i]^.Hedgehog^.Effects[heFrozen]:= 200000-1;//cHedgehogTurnTime + cReadyDelay
- PlaySound(sndHogFreeze);
- end;
- end;
- inc(Pos)
- end
- else if (t > 400) and ((gY > cWaterLine) or
- (((gX and LAND_WIDTH_MASK = 0) and (gY and LAND_HEIGHT_MASK = 0))
- and (Land[gY, gX] <> 0))) then
- begin
- Target.X:= gX;
- Target.Y:= gY;
- X:= HHGear^.X;
- Y:= HHGear^.Y
- end;
- if (gX > max(LAND_WIDTH,4096)*2) or
- (gX < -max(LAND_WIDTH,4096)) or
- (gY < -max(LAND_HEIGHT,4096)) or
- (gY > max(LAND_HEIGHT,4096)+512) then
- begin
- //X:= HHGear^.X;
- //Y:= HHGear^.Y
- Target.X:= gX;
- Target.Y:= gY;
- end
- end
- end;
-end;
-
-procedure doStepAddAmmo(Gear: PGear);
-var a: TAmmoType;
- gi: PGear;
-begin
-if Gear^.Timer > 0 then dec(Gear^.Timer)
-else
- begin
- if Gear^.Pos = posCaseUtility then
- a:= GetUtility(Gear^.Hedgehog)
- else
- a:= GetAmmo(Gear^.Hedgehog);
- CheckSum:= CheckSum xor GameTicks;
- gi := GearsList;
- while gi <> nil do
- begin
- with gi^ do CheckSum:= CheckSum xor X.round xor X.frac xor dX.round xor dX.frac xor Y.round xor Y.frac xor dY.round xor dY.frac;
- AddRandomness(CheckSum);
- if gi^.Kind = gtGenericFaller then gi^.State:= gi^.State and not gstTmpFlag;
- gi := gi^.NextGear
- end;
- AddPickup(Gear^.Hedgehog^, a, Gear^.Power, hwRound(Gear^.X), hwRound(Gear^.Y));
- DeleteGear(Gear)
- end;
-end;
-
-procedure doStepGenericFaller(Gear: PGear);
-begin
-if Gear^.Timer < $FFFFFFFF then
- if Gear^.Timer > 0 then
- dec(Gear^.Timer)
- else
- begin
- DeleteGear(Gear);
- exit
- end;
-if (Gear^.State and gstTmpFlag <> 0) or (GameTicks and $7 = 0) then
- begin
- doStepFallingGear(Gear);
- if (Gear^.State and gstInvisible <> 0) and (GameTicks and $FF = 0) and (hwRound(Gear^.X) < LongInt(leftX)) or (hwRound(Gear^.X) > LongInt(rightX)) or (hwRound(Gear^.Y) < LongInt(topY)) then
- begin
- Gear^.X:= int2hwFloat(GetRandom(rightX-leftX)+leftX);
- Gear^.Y:= int2hwFloat(GetRandom(LAND_HEIGHT-topY)+topY);
- Gear^.dX:= _90-(GetRandomf*_360);
- Gear^.dY:= _90-(GetRandomf*_360)
- end;
- end
-end;
-
-procedure doStepCreeper(Gear: PGear);
-var hogs: PGearArrayS;
- HHGear: PGear;
- tdX: hwFloat;
- dir: LongInt;
-begin
-doStepFallingGear(Gear);
-if Gear^.Timer > 0 then dec(Gear^.Timer);
-// creeper sleep phase
-if (Gear^.Hedgehog = nil) and (Gear^.Timer > 0) then exit;
-
-if Gear^.Hedgehog <> nil then HHGear:= Gear^.Hedgehog^.Gear
-else HHGear:= nil;
-
-// creeper boom phase
-if (Gear^.State and gstTmpFlag <> 0) then
- begin
- if (Gear^.Timer = 0) then
- begin
- doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 300, CurrentHedgehog, EXPLAutoSound);
- DeleteGear(Gear)
- end;
- // ssssss he essssscaped
- if (Gear^.Timer > 250) and ((HHGear = nil) or
- (((abs(HHGear^.X.Round-Gear^.X.Round) + abs(HHGear^.Y.Round-Gear^.Y.Round) + 2) > 180) and
- (Distance(HHGear^.X-Gear^.X,HHGear^.Y-Gear^.Y) > _180))) then
- begin
- Gear^.State:= Gear^.State and (not gstTmpFlag);
- Gear^.Timer:= 0
- end;
- exit
- end;
-
-// Search out a new target, as target seek time has expired, target is dead, target is out of range, or we did not have a target
-if (HHGear = nil) or (Gear^.Timer = 0) or
- (((abs(HHGear^.X.Round-Gear^.X.Round) + abs(HHGear^.Y.Round-Gear^.Y.Round) + 2) > Gear^.Angle) and
- (Distance(HHGear^.X-Gear^.X,HHGear^.Y-Gear^.Y) > int2hwFloat(Gear^.Angle)))
- then
- begin
- hogs := GearsNear(Gear^.X, Gear^.Y, gtHedgehog, Gear^.Angle);
- if hogs.size > 1 then
- Gear^.Hedgehog:= hogs.ar^[GetRandom(hogs.size)]^.Hedgehog
- else if hogs.size = 1 then Gear^.Hedgehog:= hogs.ar^[0]^.Hedgehog
- else Gear^.Hedgehog:= nil;
- if Gear^.Hedgehog <> nil then Gear^.Timer:= 5000;
- exit
- end;
-
-// we have a target. move the creeper.
-if HHGear <> nil then
- begin
- // GOTCHA
- if ((abs(HHGear^.X.Round-Gear^.X.Round) + abs(HHGear^.Y.Round-Gear^.Y.Round) + 2) < 50) and
- (Distance(HHGear^.X-Gear^.X,HHGear^.Y-Gear^.Y) < _50) then
- begin
- // hisssssssssss
- Gear^.State:= Gear^.State or gstTmpFlag;
- Gear^.Timer:= 1500;
- exit
- end;
- if (Gear^.State and gstMoving <> 0) then
- begin
- Gear^.dY:= _0;
- Gear^.dX:= _0;
- end
- else if (GameTicks and $FF = 0) then
- begin
- tdX:= HHGear^.X-Gear^.X;
- dir:= hwSign(tdX);
- if not TestCollisionX(Gear, dir) then
- Gear^.X:= Gear^.X + signAs(_1,tdX);
- if TestCollisionXwithXYShift(Gear, signAs(_10,tdX), 0, dir) then
- begin
- Gear^.dX:= SignAs(_0_15, tdX);
- Gear^.dY:= -_0_3;
- Gear^.State:= Gear^.State or gstMoving
- end
- end;
- end;
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepKnife(Gear: PGear);
-//var ox, oy: LongInt;
-// la: hwFloat;
-var a: real;
-begin
- // Gear is shrunk so it can actually escape the hog without carving into the terrain
- if (Gear^.Radius = 4) and (Gear^.CollisionMask = $FFFF) then Gear^.Radius:= 7;
- if Gear^.Damage > 100 then Gear^.CollisionMask:= 0
- else if Gear^.Damage > 30 then
- if GetRandom(max(4,18-Gear^.Damage div 10)) < 3 then Gear^.CollisionMask:= 0;
- Gear^.Damage:= 0;
- if Gear^.Timer > 0 then dec(Gear^.Timer);
- if (Gear^.State and gstMoving <> 0) and (Gear^.State and gstCollision = 0) then
- begin
- DeleteCI(Gear);
- Gear^.Radius:= 7;
- // used for damage and impact calc. needs balancing I think
- Gear^.Health:= hwRound(hwSqr((hwAbs(Gear^.dY)+hwAbs(Gear^.dX))*_4));
- doStepFallingGear(Gear);
- AllInactive := false;
- a:= Gear^.DirAngle;
- CalcRotationDirAngle(Gear);
- Gear^.DirAngle:= a+(Gear^.DirAngle-a)*2*hwSign(Gear^.dX) // double rotation
- end
- else if (Gear^.CollisionIndex = -1) and (Gear^.Timer = 0) then
- begin
- (*ox:= 0; oy:= 0;
- if TestCollisionYwithGear(Gear, -1) <> 0 then oy:= -1;
- if TestCollisionXwithGear(Gear, 1) then ox:= 1;
- if TestCollisionXwithGear(Gear, -1) then ox:= -1;
- if TestCollisionYwithGear(Gear, 1) <> 0 then oy:= 1;
- if Gear^.Health > 0 then
- PlaySound(sndRopeAttach);
-
- la:= _10000;
- if (ox <> 0) or (oy <> 0) then
- la:= CalcSlopeNearGear(Gear, ox, oy);
- if la = _10000 then
- begin
- // debug for when we couldn't get an angle
- //AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeWhite);
-*)
- Gear^.DirAngle:= DxDy2Angle(Gear^.dX, Gear^.dY) + (random(30)-15);
- if (Gear^.dX.isNegative and Gear^.dY.isNegative) or
- ((not Gear^.dX.isNegative) and (not Gear^.dY.isNegative)) then Gear^.DirAngle:= Gear^.DirAngle-90;
- // end
- // else Gear^.DirAngle:= hwFloat2Float(la)*90; // sheepluva's comment claims 45deg = 0.5 - yet orientation doesn't seem consistent?
- // AddFileLog('la: '+floattostr(la)+' DirAngle: '+inttostr(round(Gear^.DirAngle)));
- Gear^.dX:= _0;
- Gear^.dY:= _0;
- Gear^.State:= Gear^.State and (not gstMoving) or gstCollision;
- Gear^.Radius:= 16;
- if Gear^.Health > 0 then AmmoShove(Gear, Gear^.Health, 0);
- Gear^.Health:= 0;
- Gear^.Timer:= 500;
- AddGearCI(Gear)
- end
- else if GameTicks and $3F = 0 then
- begin
- if (TestCollisionYwithGear(Gear, -1) = 0)
- and (not TestCollisionXwithGear(Gear, 1))
- and (not TestCollisionXwithGear(Gear, -1))
- and (TestCollisionYwithGear(Gear, 1) = 0) then Gear^.State:= Gear^.State and (not gstCollision) or gstMoving;
- end
-end;
-(*
- This didn't end up getting used, but, who knows, might be reasonable for javellin or something
-// Make the knife initial angle based on the hog attack angle, or is that too hard?
-procedure doStepKnife(Gear: PGear);
-var t,
- gx, gy, ga, // gear x,y,angle
- lx, ly, la, // land x,y,angle
- ox, oy, // x,y offset
- w, h, // wXh of clip area
- tx, ty // tip position in sprite
- : LongInt;
- surf: PSDL_Surface;
- s: hwFloat;
-
-begin
- Gear^.dY := Gear^.dY + cGravity;
- if (GameFlags and gfMoreWind) <> 0 then
- Gear^.dX := Gear^.dX + cWindSpeed / Gear^.Density;
- Gear^.X := Gear^.X + Gear^.dX;
- Gear^.Y := Gear^.Y + Gear^.dY;
- CheckGearDrowning(Gear);
- gx:= hwRound(Gear^.X);
- gy:= hwRound(Gear^.Y);
- if Gear^.State and gstDrowning <> 0 then exit;
- with Gear^ do
- begin
- if CheckLandValue(gx, gy, lfLandMask) then
- begin
- t:= Angle + hwRound((hwAbs(dX)+hwAbs(dY)) * _10);
-
- if t < 0 then inc(t, 4096)
- else if 4095 < t then dec(t, 4096);
- Angle:= t;
-
- DirAngle:= Angle / 4096 * 360
- end
- else
- begin
-//This is the set of postions for the knife.
-//Using FlipSurface and copyToXY the knife can be written to the LandPixels at 32 positions, and an appropriate line drawn in Land.
- t:= Angle mod 1024;
- case t div 128 of
- 0: begin
- ox:= 2; oy:= 5;
- w := 25; h:= 5;
- tx:= 0; ty:= 2
- end;
- 1: begin
- ox:= 2; oy:= 15;
- w:= 24; h:= 8;
- tx:= 0; ty:= 7
- end;
- 2: begin
- ox:= 2; oy:= 27;
- w:= 23; h:= 12;
- tx:= -12; ty:= -5
- end;
- 3: begin
- ox:= 2; oy:= 43;
- w:= 21; h:= 15;
- tx:= 0; ty:= 14
- end;
- 4: begin
- ox:= 29; oy:= 8;
- w:= 19; h:= 19;
- tx:= 0; ty:= 17
- end;
- 5: begin
- ox:= 29; oy:= 32;
- w:= 15; h:= 21;
- tx:= 0; ty:= 20
- end;
- 6: begin
- ox:= 51; oy:= 3;
- w:= 11; h:= 23;
- tx:= 0; ty:= 22
- end;
- 7: begin
- ox:= 51; oy:= 34;
- w:= 7; h:= 24;
- tx:= 0; ty:= 23
- end
- end;
-
- surf:= SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, RMask, GMask, BMask, AMask);
- copyToXYFromRect(SpritesData[sprKnife].Surface, surf, ox, oy, w, h, 0, 0);
- // try to make the knife hit point first
- lx := 0;
- ly := 0;
- if CalcSlopeTangent(Gear, gx, gy, lx, ly, 255) then
- begin
- la:= vector2Angle(int2hwFloat(lx), int2hwFloat(ly));
- ga:= vector2Angle(dX, dY);
- AddFileLog('la: '+inttostr(la)+' ga: '+inttostr(ga)+' Angle: '+inttostr(Angle));
- // change to 0 to 4096 forced by LongWord in Gear
- if la < 0 then la:= 4096+la;
- if ga < 0 then ga:= 4096+ga;
- if ((Angle > ga) and (Angle < la)) or ((Angle < ga) and (Angle > la)) then
- begin
- if Angle >= 2048 then dec(Angle, 2048)
- else if Angle < 2048 then inc(Angle, 2048)
- end;
- AddFileLog('la: '+inttostr(la)+' ga: '+inttostr(ga)+' Angle: '+inttostr(Angle))
- end;
- case Angle div 1024 of
- 0: begin
- flipSurface(surf, true);
- flipSurface(surf, true);
- BlitImageAndGenerateCollisionInfo(gx-(w-tx), gy-(h-ty), w, surf)
- end;
- 1: begin
- flipSurface(surf, false);
- BlitImageAndGenerateCollisionInfo(gx-(w-tx), gy-ty, w, surf)
- end;
- 2: begin // knife was actually drawn facing this way...
- BlitImageAndGenerateCollisionInfo(gx-tx, gy-ty, w, surf)
- end;
- 3: begin
- flipSurface(surf, true);
- BlitImageAndGenerateCollisionInfo(gx-tx, gy-(h-ty), w, surf)
- end
- end;
- SDL_FreeSurface(surf);
- // this needs to calculate actual width/height + land clipping since update texture doesn't.
- // i.e. this will crash if you fire near sides of map, but until I get the blit right, not going to put real values
- UpdateLandTexture(hwRound(X)-32, 64, hwRound(Y)-32, 64, true);
- DeleteGear(Gear);
- exit
- end
- end;
-end;
-*)
--- a/hedgewars/VGSHandlers.inc Mon Jul 01 22:28:42 2013 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,802 +0,0 @@
-(*
- * Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- *)
-
-(*
- * This file contains the step handlers for visual gears.
- *
- * Since the effects of visual gears do not affect the course of the game,
- * no "synchronization" between players is required.
- * => The usage of safe functions or data types (e.g. GetRandom() or hwFloat)
- * is usually not necessary and therefore undesirable.
- *)
-
-procedure doStepFlake(Gear: PVisualGear; Steps: Longword);
-var sign: real;
- moved: boolean;
-begin
-if vobCount = 0 then exit;
-
-sign:= 1;
-with Gear^ do
- begin
- inc(FrameTicks, Steps);
- if not SuddenDeathDmg and (FrameTicks > vobFrameTicks) then
- begin
- dec(FrameTicks, vobFrameTicks);
- inc(Frame);
- if Frame = vobFramesCount then
- Frame:= 0
- end
- else if SuddenDeathDmg and (FrameTicks > vobSDFrameTicks) then
- begin
- dec(FrameTicks, vobSDFrameTicks);
- inc(Frame);
- if Frame = vobSDFramesCount then
- Frame:= 0
- end;
- X:= X + (cWindSpeedf * 400 + dX + tdX) * Steps * Gear^.Scale;
- if SuddenDeathDmg then
- Y:= Y + (dY + tdY + cGravityf * vobSDFallSpeed) * Steps * Gear^.Scale
- else
- Y:= Y + (dY + tdY + cGravityf * vobFallSpeed) * Steps * Gear^.Scale;
- Angle:= Angle + dAngle * Steps;
- if Angle > 360 then
- Angle:= Angle - 360
- else
- if Angle < - 360 then
- Angle:= Angle + 360;
-
-
- if (round(X) >= cLeftScreenBorder)
- and (round(X) <= cRightScreenBorder)
- and (round(Y) - 75 <= LAND_HEIGHT)
- and (Timer > 0) and (Timer-Steps > 0) then
- begin
- if tdX > 0 then
- sign := 1
- else
- sign:= -1;
- tdX:= tdX - 0.005*Steps*sign;
- if ((sign < 0) and (tdX > 0)) or ((sign > 0) and (tdX < 0)) then
- tdX:= 0;
- if tdX > 0 then
- sign := 1
- else
- sign:= -1;
- tdY:= tdY - 0.005*Steps*sign;
- if ((sign < 0) and (tdY > 0)) or ((sign > 0) and (tdY < 0)) then
- tdY:= 0;
- dec(Timer, Steps)
- end
- else
- begin
- moved:= false;
- if round(X) < cLeftScreenBorder then
- begin
- X:= X + cScreenSpace;
- moved:= true
- end
- else
- if round(X) > cRightScreenBorder then
- begin
- X:= X - cScreenSpace;
- moved:= true
- end;
- // if round(Y) < (LAND_HEIGHT - 1024 - 75) then Y:= Y + 25.0; // For if flag is set for flakes rising upwards?
- if (Gear^.Layer = 2) and (round(Y) - 225 > LAND_HEIGHT) then
- begin
- X:= cLeftScreenBorder + random(cScreenSpace);
- Y:= Y - (1024 + 250 + random(50)); // TODO - configure in theme (jellies for example could use limited range)
- moved:= true
- end
- else if (Gear^.Layer <> 2) and (round(Y) + 50 > LAND_HEIGHT) then
- begin
- X:= cLeftScreenBorder + random(cScreenSpace);
- Y:= Y - (1024 + random(25));
- moved:= true
- end;
- if moved then
- begin
- Angle:= random(360);
- dx:= 0.0000038654705 * random(10000);
- dy:= 0.000003506096 * random(7000);
- if random(2) = 0 then dx := -dx
- end;
- Timer:= 0;
- tdX:= 0;
- tdY:= 0
- end;
- end;
-
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepBeeTrace(Gear: PVisualGear; Steps: Longword);
-begin
-if Gear^.FrameTicks > Steps then
- dec(Gear^.FrameTicks, Steps)
-else
- DeleteVisualGear(Gear);
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepCloud(Gear: PVisualGear; Steps: Longword);
-var s: Longword;
- t: real;
-begin
-Gear^.X:= Gear^.X + (cWindSpeedf * 750 * Gear^.dX * Gear^.Scale) * Steps;
-
-// up-and-down-bounce magic
-s := (GameTicks + Gear^.Timer) mod 4096;
-t := 8 * Gear^.Scale * hwFloat2Float(AngleSin(s mod 2048));
-if (s < 2048) then t := -t;
-
-Gear^.Y := LAND_HEIGHT - 1184 + LongInt(Gear^.Timer mod 8) + t;
-
-if round(Gear^.X) < cLeftScreenBorder then
- Gear^.X:= Gear^.X + cScreenSpace
-else
- if round(Gear^.X) > cRightScreenBorder then
- Gear^.X:= Gear^.X - cScreenSpace
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepExpl(Gear: PVisualGear; Steps: Longword);
-var s: LongInt;
-begin
-s:= min(Steps, cExplFrameTicks);
-
-Gear^.X:= Gear^.X + Gear^.dX * s;
-Gear^.Y:= Gear^.Y + Gear^.dY * s;
-//Gear^.dY:= Gear^.dY + cGravityf;
-
-if Gear^.FrameTicks <= Steps then
- if Gear^.Frame = 0 then
- DeleteVisualGear(Gear)
- else
- begin
- dec(Gear^.Frame);
- Gear^.FrameTicks:= cExplFrameTicks
- end
- else dec(Gear^.FrameTicks, Steps)
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepNote(Gear: PVisualGear; Steps: Longword);
-begin
-Gear^.X:= Gear^.X + Gear^.dX * Steps;
-
-Gear^.Y:= Gear^.Y + Gear^.dY * Steps;
-Gear^.dY:= Gear^.dY + cGravityf * Steps / 2;
-
-Gear^.Angle:= Gear^.Angle + (Gear^.Frame + 1) * Steps / 10;
-while Gear^.Angle > cMaxAngle do
- Gear^.Angle:= Gear^.Angle - cMaxAngle;
-
-if Gear^.FrameTicks <= Steps then
- DeleteVisualGear(Gear)
-else
- dec(Gear^.FrameTicks, Steps)
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepLineTrail(Gear: PVisualGear; Steps: Longword);
-begin
-Steps := Steps;
-if Gear^.Timer <= Steps then
- DeleteVisualGear(Gear)
-else
- dec(Gear^.Timer, Steps)
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepEgg(Gear: PVisualGear; Steps: Longword);
-begin
-Gear^.X:= Gear^.X + Gear^.dX * Steps;
-
-Gear^.Y:= Gear^.Y + Gear^.dY * Steps;
-Gear^.dY:= Gear^.dY + cGravityf * Steps;
-
-Gear^.Angle:= round(Gear^.Angle + Steps) mod cMaxAngle;
-
-if Gear^.FrameTicks <= Steps then
- begin
- DeleteVisualGear(Gear);
- exit
- end
-else
- dec(Gear^.FrameTicks, Steps);
-
-if Gear^.FrameTicks < $FF then
- Gear^.Tint:= (Gear^.Tint and $FFFFFF00) or Gear^.FrameTicks
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepFire(Gear: PVisualGear; Steps: Longword);
-var vgt: PVisualGear;
-begin
-Gear^.X:= Gear^.X + Gear^.dX * Steps;
-
-Gear^.Y:= Gear^.Y + Gear^.dY * Steps;// + cGravityf * (Steps * Steps);
-if (Gear^.State and gstTmpFlag) = 0 then
- begin
- Gear^.dY:= Gear^.dY + cGravityf * Steps;
- if ((GameTicks mod 200) < Steps + 1) then
- begin
- vgt:= AddVisualGear(round(Gear^.X), round(Gear^.Y), vgtFire);
- if vgt <> nil then
- begin
- vgt^.dx:= 0;
- vgt^.dy:= 0;
- vgt^.State:= gstTmpFlag;
- end;
- end
- end
-else
- inc(Steps, Steps);
-
-if Gear^.FrameTicks <= Steps then
- DeleteVisualGear(Gear)
-else
- dec(Gear^.FrameTicks, Steps)
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepShell(Gear: PVisualGear; Steps: Longword);
-begin
-Gear^.X:= Gear^.X + Gear^.dX * Steps;
-
-Gear^.Y:= Gear^.Y + Gear^.dY * Steps;
-Gear^.dY:= Gear^.dY + cGravityf * Steps;
-
-Gear^.Angle:= round(Gear^.Angle + Steps) mod cMaxAngle;
-
-if Gear^.FrameTicks <= Steps then
- DeleteVisualGear(Gear)
-else
- dec(Gear^.FrameTicks, Steps)
-end;
-
-procedure doStepSmallDamage(Gear: PVisualGear; Steps: Longword);
-begin
-Gear^.Y:= Gear^.Y - 0.02 * Steps;
-
-if Gear^.FrameTicks <= Steps then
- DeleteVisualGear(Gear)
-else
- dec(Gear^.FrameTicks, Steps)
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepBubble(Gear: PVisualGear; Steps: Longword);
-begin
-Gear^.X:= Gear^.X + Gear^.dX * Steps;
-Gear^.Y:= Gear^.Y + Gear^.dY * Steps;
-Gear^.Y:= Gear^.Y - cDrownSpeedf * Steps;
-Gear^.dX := Gear^.dX / (1.001 * Steps);
-Gear^.dY := Gear^.dY / (1.001 * Steps);
-
-if (Gear^.FrameTicks <= Steps) or (round(Gear^.Y) < cWaterLine) then
- DeleteVisualGear(Gear)
-else
- dec(Gear^.FrameTicks, Steps)
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepSteam(Gear: PVisualGear; Steps: Longword);
-begin
-Gear^.X:= Gear^.X + (cWindSpeedf * 100 + Gear^.dX) * Steps;
-Gear^.Y:= Gear^.Y - cDrownSpeedf * Steps;
-
-if Gear^.FrameTicks <= Steps then
- if Gear^.Frame = 0 then
- DeleteVisualGear(Gear)
- else
- begin
- if Random(2) = 0 then
- dec(Gear^.Frame);
- Gear^.FrameTicks:= cExplFrameTicks
- end
-else dec(Gear^.FrameTicks, Steps)
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepAmmo(Gear: PVisualGear; Steps: Longword);
-begin
-Gear^.Y:= Gear^.Y - cDrownSpeedf * Steps;
-
-Gear^.scale:= Gear^.scale + 0.0025 * Steps;
-Gear^.alpha:= Gear^.alpha - 0.0015 * Steps;
-
-if Gear^.alpha < 0 then
- DeleteVisualGear(Gear)
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepSmoke(Gear: PVisualGear; Steps: Longword);
-begin
-Gear^.X:= Gear^.X + (cWindSpeedf + Gear^.dX) * Steps;
-Gear^.Y:= Gear^.Y - (cDrownSpeedf + Gear^.dY) * Steps;
-
-Gear^.dX := Gear^.dX + (cWindSpeedf * 0.3 * Steps);
-//Gear^.dY := Gear^.dY - (cDrownSpeedf * 0.995);
-
-if Gear^.FrameTicks <= Steps then
- if Gear^.Frame = 0 then
- DeleteVisualGear(Gear)
- else
- begin
- if Random(2) = 0 then
- dec(Gear^.Frame);
- Gear^.FrameTicks:= cExplFrameTicks
- end
- else dec(Gear^.FrameTicks, Steps)
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepDust(Gear: PVisualGear; Steps: Longword);
-begin
-Gear^.X:= Gear^.X + (cWindSpeedf + (cWindSpeedf * 0.03 * Steps) + Gear^.dX) * Steps;
-Gear^.Y:= Gear^.Y - (Gear^.dY) * Steps;
-
-Gear^.dX := Gear^.dX - (Gear^.dX * 0.005 * Steps);
-Gear^.dY := Gear^.dY - (cDrownSpeedf * 0.001 * Steps);
-
-if Gear^.FrameTicks <= Steps then
- if Gear^.Frame = 0 then
- DeleteVisualGear(Gear)
- else
- begin
- dec(Gear^.Frame);
- Gear^.FrameTicks:= cExplFrameTicks
- end
- else dec(Gear^.FrameTicks, Steps)
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepSplash(Gear: PVisualGear; Steps: Longword);
-begin
-if Gear^.FrameTicks <= Steps then
- DeleteVisualGear(Gear)
-else
- dec(Gear^.FrameTicks, Steps);
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepDroplet(Gear: PVisualGear; Steps: Longword);
-begin
-Gear^.X:= Gear^.X + Gear^.dX * Steps;
-
-Gear^.Y:= Gear^.Y + Gear^.dY * Steps;
-Gear^.dY:= Gear^.dY + cGravityf * Steps;
-
-if round(Gear^.Y) > cWaterLine then
- begin
- DeleteVisualGear(Gear);
- PlaySound(TSound(ord(sndDroplet1) + Random(3)));
- end;
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepSmokeRing(Gear: PVisualGear; Steps: Longword);
-begin
-inc(Gear^.Timer, Steps);
-if Gear^.Timer >= Gear^.FrameTicks then
- DeleteVisualGear(Gear)
-else
- begin
- Gear^.scale := 1.25 * (-power(2, -10 * Int(Gear^.Timer)/Gear^.FrameTicks) + 1) + 0.4;
- Gear^.alpha := 1 - power(Gear^.Timer / 350, 4);
- if Gear^.alpha < 0 then
- Gear^.alpha:= 0;
- end;
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepFeather(Gear: PVisualGear; Steps: Longword);
-begin
-Gear^.X:= Gear^.X + Gear^.dX * Steps;
-
-Gear^.Y:= Gear^.Y + Gear^.dY * Steps;
-Gear^.dY:= Gear^.dY + cGravityf * Steps;
-
-Gear^.Angle:= round(Gear^.Angle + Steps) mod cMaxAngle;
-
-if Gear^.FrameTicks <= Steps then
- DeleteVisualGear(Gear)
-else
- dec(Gear^.FrameTicks, Steps)
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-const cSorterWorkTime = 640;
-var thexchar: array[0..cMaxTeams] of
- record
- dy, ny, dw: LongInt;
- team: PTeam;
- SortFactor: QWord;
- end;
- currsorter: PVisualGear = nil;
-
-procedure doStepTeamHealthSorterWork(Gear: PVisualGear; Steps: Longword);
-var i, t: LongInt;
-begin
-for t:= 1 to min(Steps, Gear^.Timer) do
- begin
- dec(Gear^.Timer);
- if (Gear^.Timer and 15) = 0 then
- for i:= 0 to Pred(TeamsCount) do
- with thexchar[i] do
- begin
- {$WARNINGS OFF}
- team^.DrawHealthY:= ny + dy * LongInt(Gear^.Timer) div cSorterWorkTime;
- team^.TeamHealthBarWidth:= team^.NewTeamHealthBarWidth + dw * LongInt(Gear^.Timer) div cSorterWorkTime;
- {$WARNINGS ON}
- end;
- end;
-
-if (Gear^.Timer = 0) or (currsorter <> Gear) then
- begin
- if currsorter = Gear then
- currsorter:= nil;
- DeleteVisualGear(Gear);
- exit
- end
-end;
-
-procedure doStepTeamHealthSorter(Gear: PVisualGear; Steps: Longword);
-var i: Longword;
- b: boolean;
- t: LongInt;
-begin
-Steps:= Steps; // avoid compiler hint
-
-for t:= 0 to Pred(TeamsCount) do
- with thexchar[t] do
- begin
- team:= TeamsArray[t];
- dy:= team^.DrawHealthY;
- dw:= team^.TeamHealthBarWidth - team^.NewTeamHealthBarWidth;
- if team^.TeamHealth > 0 then
- begin
- SortFactor:= team^.Clan^.ClanHealth;
- SortFactor:= (SortFactor shl 3) + team^.Clan^.ClanIndex;
- SortFactor:= (SortFactor shl 30) + team^.TeamHealth;
- end
- else
- SortFactor:= 0;
- end;
-
-if TeamsCount > 1 then
- repeat
- b:= true;
- for t:= 0 to TeamsCount - 2 do
- if (thexchar[t].SortFactor > thexchar[Succ(t)].SortFactor) then
- begin
- thexchar[cMaxTeams]:= thexchar[t];
- thexchar[t]:= thexchar[Succ(t)];
- thexchar[Succ(t)]:= thexchar[cMaxTeams];
- b:= false
- end
- until b;
-
-t:= - 4;
-for i:= 0 to Pred(TeamsCount) do
- with thexchar[i] do
- if team^.TeamHealth > 0 then
- begin
- dec(t, team^.HealthTex^.h + 2);
- ny:= t;
- dy:= dy - ny
- end;
-
-Gear^.Timer:= cSorterWorkTime;
-Gear^.doStep:= @doStepTeamHealthSorterWork;
-currsorter:= Gear;
-//doStepTeamHealthSorterWork(Gear, Steps)
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepSpeechBubbleWork(Gear: PVisualGear; Steps: Longword);
-begin
-if Gear^.Timer > Steps then dec(Gear^.Timer, Steps) else Gear^.Timer:= 0;
-
-if (Gear^.Hedgehog^.Gear <> nil) then
- begin
- Gear^.X:= hwFloat2Float(Gear^.Hedgehog^.Gear^.X) + (Gear^.Tex^.w div 2 - Gear^.FrameTicks);
- Gear^.Y:= hwFloat2Float(Gear^.Hedgehog^.Gear^.Y) - (16 + Gear^.Tex^.h);
- end;
-
-if Gear^.Timer = 0 then
- begin
- if Gear^.Hedgehog^.SpeechGear = Gear then
- Gear^.Hedgehog^.SpeechGear:= nil;
- DeleteVisualGear(Gear)
- end;
-end;
-
-procedure doStepSpeechBubble(Gear: PVisualGear; Steps: Longword);
-begin
-Steps:= Steps; // avoid compiler hint
-
-with Gear^.Hedgehog^ do
- if SpeechGear <> nil then
- SpeechGear^.Timer:= 0;
-
-Gear^.Hedgehog^.SpeechGear:= Gear;
-
-Gear^.Timer:= max(LongInt(Length(Gear^.Text)) * 150, 3000);
-
-Gear^.Tex:= RenderSpeechBubbleTex(Gear^.Text, Gear^.FrameTicks, fnt16);
-
-case Gear^.FrameTicks of
- 1: Gear^.FrameTicks:= SpritesData[sprSpeechTail].Width-28;
- 2: Gear^.FrameTicks:= SpritesData[sprThoughtTail].Width-20;
- 3: Gear^.FrameTicks:= SpritesData[sprShoutTail].Width-10;
- end;
-
-Gear^.doStep:= @doStepSpeechBubbleWork;
-
-Gear^.Y:= Gear^.Y - Gear^.Tex^.h
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepHealthTagWork(Gear: PVisualGear; Steps: Longword);
-begin
-if Steps > Gear^.Timer then
- DeleteVisualGear(Gear)
-else
- begin
- dec(Gear^.Timer, Steps);
- Gear^.Y:= Gear^.Y + Gear^.dY * Steps;
- Gear^.X:= Gear^.X + Gear^.dX * Steps
- end;
-end;
-
-procedure doStepHealthTagWorkUnderWater(Gear: PVisualGear; Steps: Longword);
-begin
-if round(Gear^.Y) - 10 < cWaterLine then
- DeleteVisualGear(Gear)
-else
- Gear^.Y:= Gear^.Y - 0.08 * Steps;
-
-end;
-
-procedure doStepHealthTag(Gear: PVisualGear; Steps: Longword);
-var s: shortstring;
-begin
-s:= '';
-
-str(Gear^.State, s);
-if Gear^.Hedgehog <> nil then
- Gear^.Tex:= RenderStringTex(s, Gear^.Hedgehog^.Team^.Clan^.Color, fnt16)
-else
- Gear^.Tex:= RenderStringTex(s, cWhiteColor, fnt16);
-
-Gear^.doStep:= @doStepHealthTagWork;
-
-if (round(Gear^.Y) > cWaterLine) and (Gear^.Frame = 0) then
- Gear^.doStep:= @doStepHealthTagWorkUnderWater;
-
-Gear^.Y:= Gear^.Y - Gear^.Tex^.h;
-
-if Steps > 1 then
- Gear^.doStep(Gear, Steps-1);
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepSmokeTrace(Gear: PVisualGear; Steps: Longword);
-begin
-inc(Gear^.Timer, Steps );
-if Gear^.Timer > 64 then
- begin
- if Gear^.State = 0 then
- begin
- DeleteVisualGear(Gear);
- exit;
- end;
- dec(Gear^.State, Gear^.Timer div 65);
- Gear^.Timer:= Gear^.Timer mod 65;
- end;
-Gear^.dX:= Gear^.dX + cWindSpeedf * Steps;
-Gear^.X:= Gear^.X + Gear^.dX;
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepExplosionWork(Gear: PVisualGear; Steps: Longword);
-begin
-inc(Gear^.Timer, Steps);
-if Gear^.Timer > 75 then
- begin
- inc(Gear^.State, Gear^.Timer div 76);
- Gear^.Timer:= Gear^.Timer mod 76;
- if Gear^.State > 5 then
- DeleteVisualGear(Gear);
- end;
-end;
-
-procedure doStepExplosion(Gear: PVisualGear; Steps: Longword);
-var i: LongWord;
- gX,gY: LongInt;
- vg: PVisualGear;
-begin
-gX:= round(Gear^.X);
-gY:= round(Gear^.Y);
-for i:= 0 to 31 do
- begin
- vg:= AddVisualGear(gX, gY, vgtFire);
- if vg <> nil then
- begin
- vg^.State:= gstTmpFlag;
- inc(vg^.FrameTicks, vg^.FrameTicks)
- end
- end;
-for i:= 0 to 8 do AddVisualGear(gX, gY, vgtExplPart);
-for i:= 0 to 8 do AddVisualGear(gX, gY, vgtExplPart2);
-Gear^.doStep:= @doStepExplosionWork;
-if Steps > 1 then
- Gear^.doStep(Gear, Steps-1);
-end;
-
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepBigExplosionWork(Gear: PVisualGear; Steps: Longword);
-var maxMovement: LongInt;
-begin
-
-inc(Gear^.Timer, Steps);
-if (Gear^.Timer and 5) = 0 then
- begin
- maxMovement := max(1, 13 - ((Gear^.Timer * 15) div 250));
- ShakeCamera(maxMovement);
- end;
-
-if Gear^.Timer > 250 then
- DeleteVisualGear(Gear);
-end;
-
-procedure doStepBigExplosion(Gear: PVisualGear; Steps: Longword);
-var i: LongWord;
- gX,gY: LongInt;
- vg: PVisualGear;
-begin
-//ScreenFade:= sfFromWhite;
-//ScreenFadeValue:= round(60 * zoom * zoom);
-//ScreenFadeSpeed:= 5;
-gX:= round(Gear^.X);
-gY:= round(Gear^.Y);
-AddVisualGear(gX, gY, vgtSmokeRing);
-for i:= 0 to 46 do
- begin
- vg:= AddVisualGear(gX, gY, vgtFire);
- if vg <> nil then
- begin
- vg^.State:= gstTmpFlag;
- inc(vg^.FrameTicks, vg^.FrameTicks)
- end
- end;
-for i:= 0 to 15 do
- AddVisualGear(gX, gY, vgtExplPart);
-for i:= 0 to 15 do
- AddVisualGear(gX, gY, vgtExplPart2);
-Gear^.doStep:= @doStepBigExplosionWork;
-if Steps > 1 then
- Gear^.doStep(Gear, Steps-1);
-with mobileRecord do
- if (performRumble <> nil) and (not fastUntilLag) then
- performRumble(kSystemSoundID_Vibrate);
-end;
-
-procedure doStepChunk(Gear: PVisualGear; Steps: Longword);
-begin
-Gear^.X:= Gear^.X + Gear^.dX * Steps;
-
-Gear^.Y:= Gear^.Y + Gear^.dY * Steps;
-Gear^.dY:= Gear^.dY + cGravityf * Steps;
-
-Gear^.Angle:= round(Gear^.Angle + Steps) mod cMaxAngle;
-
-if (round(Gear^.Y) > cWaterLine) and ((cReducedQuality and rqPlainSplash) = 0) then
- begin
- AddVisualGear(round(Gear^.X), round(Gear^.Y), vgtDroplet);
- DeleteVisualGear(Gear);
- end
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepBulletHit(Gear: PVisualGear; Steps: Longword);
-begin
-if Gear^.FrameTicks <= Steps then
- DeleteVisualGear(Gear)
-else
- dec(Gear^.FrameTicks, Steps);
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepCircle(Gear: PVisualGear; Steps: Longword);
-var tmp: LongInt;
- i: LongWord;
-begin
-with Gear^ do
- if Frame <> 0 then
- for i:= 1 to Steps do
- begin
- inc(FrameTicks);
- if (FrameTicks mod Frame) = 0 then
- begin
- tmp:= Gear^.Tint and $FF;
- if tdY >= 0 then
- inc(tmp)
- else
- dec(tmp);
- if tmp < round(dX) then
- tdY:= 1;
- if tmp > round(dY) then
- tdY:= -1;
- if tmp > 255 then
- tmp := 255;
- if tmp < 0 then
- tmp := 0;
- Gear^.Tint:= (Gear^.Tint and $FFFFFF00) or Longword(tmp)
- end
- end
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepSmoothWindBar(Gear: PVisualGear; Steps: Longword);
-begin
-inc(Gear^.Timer, Steps);
-
-while Gear^.Timer >= 10 do
- begin
- dec(Gear^.Timer, 10);
- if WindBarWidth < Gear^.Tag then
- inc(WindBarWidth)
- else if WindBarWidth > Gear^.Tag then
- dec(WindBarWidth);
- end;
-if cWindspeedf > Gear^.dAngle then
- begin
- cWindspeedf := cWindspeedf - Gear^.Angle*Steps;
- if cWindspeedf < Gear^.dAngle then cWindspeedf:= Gear^.dAngle;
- end
-else if cWindspeedf < Gear^.dAngle then
- begin
- cWindspeedf := cWindspeedf + Gear^.Angle*Steps;
- if cWindspeedf > Gear^.dAngle then cWindspeedf:= Gear^.dAngle;
- end;
-
-if (WindBarWidth = Gear^.Tag) and (cWindspeedf = Gear^.dAngle) then
- DeleteVisualGear(Gear)
-end;
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepStraightShot(Gear: PVisualGear; Steps: Longword);
-begin
-Gear^.X:= Gear^.X + Gear^.dX * Steps;
-Gear^.Y:= Gear^.Y - Gear^.dY * Steps;
-
-if Gear^.FrameTicks <= Steps then
- DeleteVisualGear(Gear)
-else
- begin
- dec(Gear^.FrameTicks, Steps);
- if (Gear^.FrameTicks < 501) and (Gear^.FrameTicks mod 5 = 0) then
- Gear^.Tint:= (Gear^.Tint and $FFFFFF00) or (((Gear^.Tint and $000000FF) * Gear^.FrameTicks) div 500)
- end
-end;
-
--- a/hedgewars/hwengine.pas Mon Jul 01 22:28:42 2013 +0300
+++ b/hedgewars/hwengine.pas Mon Jul 01 23:23:22 2013 +0300
@@ -32,14 +32,12 @@
uses SDLh, uMisc, uConsole, uGame, uConsts, uLand, uAmmos, uVisualGears, uGears, uStore, uWorld, uInputHandler
, uSound, uScript, uTeams, uStats, uIO, uLocale, uChat, uAI, uAIMisc, uAILandMarks, uLandTexture, uCollisions
, SysUtils, uTypes, uVariables, uCommands, uUtils, uCaptions, uDebug, uCommandHandlers, uLandPainted
- , uPhysFSLayer, uCursor, uRandom
+ , uPhysFSLayer, uCursor, uRandom, ArgParsers, uVisualGearsHandlers
{$IFDEF USE_VIDEO_RECORDING}, uVideoRec {$ENDIF}
{$IFDEF USE_TOUCH_INTERFACE}, uTouch {$ENDIF}
{$IFDEF ANDROID}, GLUnit{$ENDIF}
;
-var isInternal: Boolean;
-
{$IFDEF HWLIBRARY}
procedure preInitEverything();
procedure initEverything(complete:boolean);
@@ -54,8 +52,6 @@
procedure freeEverything(complete:boolean); forward;
{$ENDIF}
-{$INCLUDE "ArgParsers.inc"}
-
///////////////////////////////////////////////////////////////////////////////
function DoTimer(Lag: LongInt): boolean;
var s: shortstring;
@@ -461,6 +457,7 @@
uStore.initModule;
uTeams.initModule;
uVisualGears.initModule;
+ uVisualGearsHandlers.initModule;
uWorld.initModule;
end;
end;
--- a/hedgewars/uCollisions.pas Mon Jul 01 22:28:42 2013 +0300
+++ b/hedgewars/uCollisions.pas Mon Jul 01 23:23:22 2013 +0300
@@ -33,7 +33,7 @@
procedure initModule;
procedure freeModule;
-procedure AddGearCI(Gear: PGear);
+procedure AddCI(Gear: PGear);
procedure DeleteCI(Gear: PGear);
function CheckGearsCollision(Gear: PGear): PGearArray;
@@ -72,7 +72,7 @@
cinfos: array[0..MAXRECTSINDEX] of TCollisionEntry;
ga: TGearArray;
-procedure AddGearCI(Gear: PGear);
+procedure AddCI(Gear: PGear);
var t: PGear;
begin
if Gear^.CollisionIndex >= 0 then
@@ -237,12 +237,14 @@
for i:= 0 to Pred(Count) do
with cinfos[i] do
- if (Gear <> cGear) and (sqr(mx - x) + sqr(my - y) <= sqr(Radius + Gear^.Radius + 2))
- and ((mx > x) xor (Dir > 0)) and
+ if (Gear <> cGear) and
+ ((mx > x) xor (Dir > 0)) and
(
((cGear^.Kind in [gtHedgehog, gtMine, gtKnife]) and ((Gear^.State and gstNotKickable) = 0)) or
// only apply X kick if the barrel is knocked over
- ((cGear^.Kind = gtExplosives) and ((cGear^.State and gsttmpflag) <> 0))) then
+ ((cGear^.Kind = gtExplosives) and ((cGear^.State and gsttmpflag) <> 0))
+ ) and
+ (sqr(mx - x) + sqr(my - y) <= sqr(Radius + Gear^.Radius + 2)) then
begin
with cGear^ do
begin
@@ -300,11 +302,11 @@
for i:= 0 to Pred(Count) do
with cinfos[i] do
- if (Gear <> cGear) and (sqr(mx - x) + sqr(my - y) <= sqr(Radius + Gear^.Radius + 2))
- and ((myr > y) xor (Dir > 0)) and
- (
- (cGear^.Kind in [gtHedgehog, gtMine, gtKnife, gtExplosives]) and
- ((Gear^.State and gstNotKickable) = 0)) then
+ if (Gear <> cGear) and
+ ((myr > y) xor (Dir > 0)) and
+ (Gear^.State and gstNotKickable = 0) and
+ (cGear^.Kind in [gtHedgehog, gtMine, gtKnife, gtExplosives]) and
+ (sqr(mx - x) + sqr(my - y) <= sqr(Radius + Gear^.Radius + 2)) then
begin
with cGear^ do
begin
--- a/hedgewars/uCommands.pas Mon Jul 01 22:28:42 2013 +0300
+++ b/hedgewars/uCommands.pas Mon Jul 01 23:23:22 2013 +0300
@@ -36,7 +36,7 @@
procedure StopMessages(Message: Longword);
implementation
-uses uConsts, uVariables, uConsole, uUtils, uDebug, SDLh;
+uses uConsts, uVariables, uConsole, uUtils, SDLh;
type PVariable = ^TVariable;
TVariable = record
@@ -52,12 +52,14 @@
begin
RegisterVariable(Name, p, Trusted, false);
end;
+
procedure RegisterVariable(Name: shortstring; p: TCommandHandler; Trusted: boolean; Rand: boolean);
-var
- value: PVariable;
+var value: PVariable;
begin
New(value);
-TryDo(value <> nil, 'RegisterVariable: value = nil', true);
+if value = nil then
+ ParseCommand('fatal RegisterVariable: value = nil', true);
+
FillChar(value^, sizeof(TVariable), 0);
value^.Name:= Name;
value^.Handler:= p;
--- a/hedgewars/uDebug.pas Mon Jul 01 22:28:42 2013 +0300
+++ b/hedgewars/uDebug.pas Mon Jul 01 23:23:22 2013 +0300
@@ -33,11 +33,7 @@
begin
WriteLnToConsole(Msg);
if isFatalError then
- begin
ParseCommand('fatal ' + lastConsoleline, true);
- SDL_Quit;
- halt(1)
- end
end;
procedure TryDo(Assert: boolean; Msg: shortstring; isFatal: boolean);
--- a/hedgewars/uGame.pas Mon Jul 01 22:28:42 2013 +0300
+++ b/hedgewars/uGame.pas Mon Jul 01 23:23:22 2013 +0300
@@ -27,7 +27,7 @@
implementation
////////////////////
uses uInputHandler, uTeams, uIO, uAI, uGears, uSound, uLocale, uCaptions,
- uVisualGears, uTypes, uVariables, uCommands, uConsts
+ uVisualGears, uTypes, uVariables, uCommands, uConsts, uVisualGearsList
{$IFDEF USE_TOUCH_INTERFACE}, uTouch{$ENDIF};
procedure DoGameTick(Lag: LongInt);
--- a/hedgewars/uGears.pas Mon Jul 01 22:28:42 2013 +0300
+++ b/hedgewars/uGears.pas Mon Jul 01 23:23:22 2013 +0300
@@ -33,60 +33,37 @@
* effects are called "Visual Gears" and defined in the respective unit!
*)
interface
-uses SDLh, uConsts, uFloat, uTypes;
+uses uConsts, uFloat, uTypes;
procedure initModule;
procedure freeModule;
function SpawnCustomCrateAt(x, y: LongInt; crate: TCrateType; content, cnt: Longword): PGear;
function SpawnFakeCrateAt(x, y: LongInt; crate: TCrateType; explode: boolean; poison: boolean ): PGear;
-function GetAmmo(Hedgehog: PHedgehog): TAmmoType;
-function GetUtility(Hedgehog: PHedgehog): TAmmoType;
-procedure HideHog(HH: PHedgehog);
procedure ProcessGears;
procedure EndTurnCleanup;
-procedure SetAllToActive;
-procedure SetAllHHToActive; inline;
-procedure SetAllHHToActive(Ice: boolean);
procedure DrawGears;
procedure FreeGearsList;
procedure AddMiscGears;
procedure AssignHHCoords;
function GearByUID(uid : Longword) : PGear;
-procedure doStepDrowningGear(Gear: PGear);
-
implementation
-uses uStore, uSound, uTeams, uRandom, uCollisions, uIO, uLandGraphics, {$IFDEF SDL13}uTouch,{$ENDIF}
- uLocale, uAI, uAmmos, uStats, uVisualGears, uScript, GLunit, uVariables,
+uses uStore, uSound, uTeams, uRandom, uIO, uLandGraphics, {$IFDEF SDL13}uTouch,{$ENDIF}
+ uLocale, uAmmos, uStats, uVisualGears, uScript, uVariables,
uCommands, uUtils, uTextures, uRenderUtils, uGearsRender, uCaptions, uDebug, uLandTexture,
- uGearsHedgehog, uGearsUtils, uGearsList, uGearsHandlers, uGearsHandlersRope;
+ uGearsHedgehog, uGearsUtils, uGearsList, uGearsHandlersRope
+ , uVisualGearsList, uGearsHandlersMess, uAI;
var skipFlag: boolean;
-procedure AmmoShove(Ammo: PGear; Damage, Power: LongInt); forward;
-//procedure AmmoFlameWork(Ammo: PGear); forward;
-function GearsNear(X, Y: hwFloat; Kind: TGearType; r: LongInt): PGearArrayS; forward;
-procedure SpawnBoxOfSmth; forward;
-procedure ShotgunShot(Gear: PGear); forward;
-procedure doStepCase(Gear: PGear); forward;
-
-
var delay: LongWord;
delay2: LongWord;
step: (stDelay, stChDmg, stSweep, stTurnReact,
stAfterDelay, stChWin, stWater, stChWin2, stHealth,
stSpawn, stNTurn);
- upd: Longword;
- snowLeft,snowRight: LongInt;
NewTurnTick: LongWord;
//SDMusic: shortstring;
-// For better maintainability the step handlers of gears are stored in
-// separate files.
-// Note: step handlers of gears that are hedgehogs are in a different file
-// than the handlers for all other gears.
-{$INCLUDE "GSHandlers.inc"}
-
function CheckNoDamage: boolean; // returns TRUE in case of no damaged hhs
var Gear: PGear;
dmg: LongInt;
@@ -335,7 +312,7 @@
ChangeToSDClouds;
ChangeToSDFlakes;
- glClearColor(SDSkyColor.r * (SDTint/255) / 255, SDSkyColor.g * (SDTint/255) / 255, SDSkyColor.b * (SDTint/255) / 255, 0.99);
+ SetSkyColor(SDSkyColor.r * (SDTint/255) / 255, SDSkyColor.g * (SDTint/255) / 255, SDSkyColor.b * (SDTint/255) / 255);
Ammoz[amTardis].SkipTurns:= 9999;
Ammoz[amTardis].Probability:= 0;
end;
@@ -550,39 +527,6 @@
RecountTeamHealth(TeamsArray[i])
end;
-procedure SetAllToActive;
-var t: PGear;
-begin
-AllInactive:= false;
-t:= GearsList;
-while t <> nil do
- begin
- t^.Active:= true;
- t:= t^.NextGear
- end
-end;
-
-procedure SetAllHHToActive; inline;
-begin
-SetAllHHToActive(true)
-end;
-
-procedure SetAllHHToActive(Ice: boolean);
-var t: PGear;
-begin
-AllInactive:= false;
-t:= GearsList;
-while t <> nil do
- begin
- if (t^.Kind = gtHedgehog) or (t^.Kind = gtExplosives) then
- begin
- if (t^.Kind = gtHedgehog) and Ice then CheckIce(t);
- t^.Active:= true
- end;
- t:= t^.NextGear
- end
-end;
-
procedure DrawGears;
var Gear: PGear;
x, y: LongInt;
@@ -677,210 +621,6 @@
AddGear(LongInt(GetRandom(snowRight - snowLeft)) + snowLeft, LAND_HEIGHT + LongInt(GetRandom(750)) - 1300, gtFlake, 0, _0, _0, 0);
end;
-
-procedure ShotgunShot(Gear: PGear);
-var t: PGear;
- dmg, r, dist: LongInt;
- dx, dy: hwFloat;
-begin
-Gear^.Radius:= cShotgunRadius;
-t:= GearsList;
-while t <> nil do
- begin
- case t^.Kind of
- gtHedgehog,
- gtMine,
- gtSMine,
- gtKnife,
- gtCase,
- gtTarget,
- gtExplosives: begin//,
-// gtStructure: begin
-//addFileLog('ShotgunShot radius: ' + inttostr(Gear^.Radius) + ', t^.Radius = ' + inttostr(t^.Radius) + ', distance = ' + inttostr(dist) + ', dmg = ' + inttostr(dmg));
- dmg:= 0;
- r:= Gear^.Radius + t^.Radius;
- dx:= Gear^.X-t^.X;
- dx.isNegative:= false;
- dy:= Gear^.Y-t^.Y;
- dy.isNegative:= false;
- if r-hwRound(dx+dy) > 0 then
- begin
- dist:= hwRound(Distance(dx, dy));
- dmg:= ModifyDamage(min(r - dist, 25), t);
- end;
- if dmg > 0 then
- begin
- if (not t^.Invulnerable) then
- ApplyDamage(t, Gear^.Hedgehog, dmg, dsBullet)
- else
- Gear^.State:= Gear^.State or gstWinner;
-
- DeleteCI(t);
- t^.dX:= t^.dX + Gear^.dX * dmg * _0_01 + SignAs(cHHKick, Gear^.dX);
- t^.dY:= t^.dY + Gear^.dY * dmg * _0_01;
- t^.State:= t^.State or gstMoving;
- if t^.Kind = gtKnife then t^.State:= t^.State and (not gstCollision);
- t^.Active:= true;
- FollowGear:= t
- end
- end;
- gtGrave: begin
- dmg:= 0;
- r:= Gear^.Radius + t^.Radius;
- dx:= Gear^.X-t^.X;
- dx.isNegative:= false;
- dy:= Gear^.Y-t^.Y;
- dy.isNegative:= false;
- if r-hwRound(dx+dy) > 0 then
- begin
- dist:= hwRound(Distance(dx, dy));
- dmg:= ModifyDamage(min(r - dist, 25), t);
- end;
- if dmg > 0 then
- begin
- t^.dY:= - _0_1;
- t^.Active:= true
- end
- end;
- end;
- t:= t^.NextGear
- end;
-if (GameFlags and gfSolidLand) = 0 then
- DrawExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), cShotgunRadius)
-end;
-
-procedure AmmoShove(Ammo: PGear; Damage, Power: LongInt);
-var t: PGearArray;
- Gear: PGear;
- i, j, tmpDmg: LongInt;
- VGear: PVisualGear;
-begin
-t:= CheckGearsCollision(Ammo);
-// Just to avoid hogs on rope dodging fire.
-if (CurAmmoGear <> nil) and ((CurAmmoGear^.Kind = gtRope) or (CurAmmoGear^.Kind = gtJetpack) or (CurAmmoGear^.Kind = gtBirdy))
-and (CurrentHedgehog^.Gear <> nil) and (CurrentHedgehog^.Gear^.CollisionIndex = -1)
-and (sqr(hwRound(Ammo^.X) - hwRound(CurrentHedgehog^.Gear^.X)) + sqr(hwRound(Ammo^.Y) - hwRound(CurrentHedgehog^.Gear^.Y)) <= sqr(cHHRadius + Ammo^.Radius)) then
- begin
- t^.ar[t^.Count]:= CurrentHedgehog^.Gear;
- inc(t^.Count)
- end;
-
-i:= t^.Count;
-
-if (Ammo^.Kind = gtFlame) and (i > 0) then
- Ammo^.Health:= 0;
-while i > 0 do
- begin
- dec(i);
- Gear:= t^.ar[i];
- if ((Ammo^.Kind = gtFlame) or (Ammo^.Kind = gtBlowTorch)) and
- (Gear^.Kind = gtHedgehog) and (Gear^.Hedgehog^.Effects[heFrozen] > 255) then
- Gear^.Hedgehog^.Effects[heFrozen]:= max(255,Gear^.Hedgehog^.Effects[heFrozen]-10000);
- tmpDmg:= ModifyDamage(Damage, Gear);
- if (Gear^.State and gstNoDamage) = 0 then
- begin
-
- if (Ammo^.Kind = gtDEagleShot) or (Ammo^.Kind = gtSniperRifleShot) then
- begin
- VGear := AddVisualGear(hwround(Ammo^.X), hwround(Ammo^.Y), vgtBulletHit);
- if VGear <> nil then
- VGear^.Angle := DxDy2Angle(-Ammo^.dX, Ammo^.dY);
- end;
-
- if (Gear^.Kind = gtHedgehog) and (Ammo^.State and gsttmpFlag <> 0) and (Ammo^.Kind = gtShover) then
- Gear^.FlightTime:= 1;
-
-
- case Gear^.Kind of
- gtHedgehog,
- gtMine,
- gtSMine,
- gtKnife,
- gtTarget,
- gtCase,
- gtExplosives: //,
- //gtStructure:
- begin
- if (Ammo^.Kind = gtDrill) then
- begin
- Ammo^.Timer:= 0;
- exit;
- end;
- if (not Gear^.Invulnerable) then
- begin
- if (Ammo^.Kind = gtKnife) and (tmpDmg > 0) then
- for j:= 1 to max(1,min(3,tmpDmg div 5)) do
- begin
- VGear:= AddVisualGear(hwRound(Ammo^.X-((Ammo^.X-Gear^.X)/_2)), hwRound(Ammo^.Y-((Ammo^.Y-Gear^.Y)/_2)), vgtStraightShot);
- if VGear <> nil then
- with VGear^ do
- begin
- Tint:= $FFCC00FF;
- Angle:= random(360);
- dx:= 0.0005 * (random(100));
- dy:= 0.0005 * (random(100));
- if random(2) = 0 then
- dx := -dx;
- if random(2) = 0 then
- dy := -dy;
- FrameTicks:= 600+random(200);
- State:= ord(sprStar)
- end
- end;
- ApplyDamage(Gear, Ammo^.Hedgehog, tmpDmg, dsShove)
- end
- else
- Gear^.State:= Gear^.State or gstWinner;
- if (Gear^.Kind = gtExplosives) and (Ammo^.Kind = gtBlowtorch) then
- begin
- if (Ammo^.Hedgehog^.Gear <> nil) then
- Ammo^.Hedgehog^.Gear^.State:= Ammo^.Hedgehog^.Gear^.State and (not gstNotKickable);
- ApplyDamage(Gear, Ammo^.Hedgehog, tmpDmg * 100, dsUnknown); // crank up damage for explosives + blowtorch
- end;
-
- if (Gear^.Kind = gtHedgehog) and (Gear^.Hedgehog^.King or (Gear^.Hedgehog^.Effects[heFrozen] > 0)) then
- begin
- Gear^.dX:= Ammo^.dX * Power * _0_005;
- Gear^.dY:= Ammo^.dY * Power * _0_005
- end
- else if ((Ammo^.Kind <> gtFlame) or (Gear^.Kind = gtHedgehog)) and (Power <> 0) then
- begin
- Gear^.dX:= Ammo^.dX * Power * _0_01;
- Gear^.dY:= Ammo^.dY * Power * _0_01
- end;
-
- if (not isZero(Gear^.dX)) or (not isZero(Gear^.dY)) then
- begin
- Gear^.Active:= true;
- DeleteCI(Gear);
- Gear^.State:= Gear^.State or gstMoving;
- if Gear^.Kind = gtKnife then Gear^.State:= Gear^.State and (not gstCollision);
- // move the gear upwards a bit to throw it over tiny obstacles at start
- if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then
- begin
- if not (TestCollisionXwithXYShift(Gear, _0, -3, hwSign(Gear^.dX))
- or (TestCollisionYwithGear(Gear, -1) <> 0)) then
- Gear^.Y:= Gear^.Y - _1;
- if not (TestCollisionXwithXYShift(Gear, _0, -2, hwSign(Gear^.dX))
- or (TestCollisionYwithGear(Gear, -1) <> 0)) then
- Gear^.Y:= Gear^.Y - _1;
- if not (TestCollisionXwithXYShift(Gear, _0, -1, hwSign(Gear^.dX))
- or (TestCollisionYwithGear(Gear, -1) <> 0)) then
- Gear^.Y:= Gear^.Y - _1;
- end
- end;
-
-
- if (Ammo^.Kind <> gtFlame) or ((Ammo^.State and gsttmpFlag) = 0) then
- FollowGear:= Gear
- end;
- end
- end;
- end;
-if i <> 0 then
- SetAllToActive
-end;
-
procedure AssignHHCoords;
var i, t, p, j: LongInt;
ar: array[0..Pred(cMaxHHs)] of PHedgehog;
@@ -945,31 +685,6 @@
end
end;
-var GearsNearArray : TPGearArray;
-function GearsNear(X, Y: hwFloat; Kind: TGearType; r: LongInt): PGearArrayS;
-var
- t: PGear;
- s: Longword;
-begin
- r:= r*r;
- s:= 0;
- SetLength(GearsNearArray, s);
- t := GearsList;
- while t <> nil do
- begin
- if (t^.Kind = Kind)
- and ((X - t^.X)*(X - t^.X) + (Y - t^.Y)*(Y-t^.Y) < int2hwFloat(r)) then
- begin
- inc(s);
- SetLength(GearsNearArray, s);
- GearsNearArray[s - 1] := t;
- end;
- t := t^.NextGear;
- end;
-
- GearsNear.size:= s;
- GearsNear.ar:= @GearsNearArray
-end;
{procedure AmmoFlameWork(Ammo: PGear);
var t: PGear;
@@ -992,21 +707,6 @@
end;}
-function CountGears(Kind: TGearType): Longword;
-var t: PGear;
- count: Longword = 0;
-begin
-
-t:= GearsList;
-while t <> nil do
- begin
- if t^.Kind = Kind then
- inc(count);
- t:= t^.NextGear
- end;
-CountGears:= count;
-end;
-
function SpawnCustomCrateAt(x, y: LongInt; crate: TCrateType; content, cnt: Longword): PGear;
begin
FollowGear := AddGear(x, y, gtCase, 0, _0, _0, 0);
@@ -1079,142 +779,6 @@
SpawnFakeCrateAt := FollowGear;
end;
-function GetAmmo(Hedgehog: PHedgehog): TAmmoType;
-var t, aTot: LongInt;
- i: TAmmoType;
-begin
-Hedgehog:= Hedgehog; // avoid hint
-
-aTot:= 0;
-for i:= Low(TAmmoType) to High(TAmmoType) do
- if (Ammoz[i].Ammo.Propz and ammoprop_Utility) = 0 then
- inc(aTot, Ammoz[i].Probability);
-
-t:= aTot;
-i:= Low(TAmmoType);
-if (t > 0) then
- begin
- t:= GetRandom(t);
- while t >= 0 do
- begin
- inc(i);
- if (Ammoz[i].Ammo.Propz and ammoprop_Utility) = 0 then
- dec(t, Ammoz[i].Probability)
- end
- end;
-GetAmmo:= i
-end;
-
-function GetUtility(Hedgehog: PHedgehog): TAmmoType;
-var t, uTot: LongInt;
- i: TAmmoType;
-begin
-
-uTot:= 0;
-for i:= Low(TAmmoType) to High(TAmmoType) do
- if ((Ammoz[i].Ammo.Propz and ammoprop_Utility) <> 0)
- and ((Hedgehog^.Team^.HedgehogsNumber > 1) or (Ammoz[i].Ammo.AmmoType <> amSwitch)) then
- inc(uTot, Ammoz[i].Probability);
-
-t:= uTot;
-i:= Low(TAmmoType);
-if (t > 0) then
- begin
- t:= GetRandom(t);
- while t >= 0 do
- begin
- inc(i);
- if ((Ammoz[i].Ammo.Propz and ammoprop_Utility) <> 0) and ((Hedgehog^.Team^.HedgehogsNumber > 1)
- or (Ammoz[i].Ammo.AmmoType <> amSwitch)) then
- dec(t, Ammoz[i].Probability)
- end
- end;
-GetUtility:= i
-end;
-
-
-
-procedure SpawnBoxOfSmth;
-var t, aTot, uTot, a, h: LongInt;
- i: TAmmoType;
-begin
-if (PlacingHogs) or
- (cCaseFactor = 0)
- or (CountGears(gtCase) >= 5)
- or (GetRandom(cCaseFactor) <> 0) then
- exit;
-
-FollowGear:= nil;
-aTot:= 0;
-uTot:= 0;
-for i:= Low(TAmmoType) to High(TAmmoType) do
- if (Ammoz[i].Ammo.Propz and ammoprop_Utility) = 0 then
- inc(aTot, Ammoz[i].Probability)
- else
- inc(uTot, Ammoz[i].Probability);
-
-t:=0;
-a:=aTot;
-h:= 1;
-
-if (aTot+uTot) <> 0 then
- if ((GameFlags and gfInvulnerable) = 0) then
- begin
- h:= cHealthCaseProb * 100;
- t:= GetRandom(10000);
- a:= (10000-h)*aTot div (aTot+uTot)
- end
- else
- begin
- t:= GetRandom(aTot+uTot);
- h:= 0
- end;
-
-
-if t<h then
- begin
- FollowGear:= AddGear(0, 0, gtCase, 0, _0, _0, 0);
- FollowGear^.Health:= cHealthCaseAmount;
- FollowGear^.Pos:= posCaseHealth;
- AddCaption(GetEventString(eidNewHealthPack), cWhiteColor, capgrpAmmoInfo);
- end
-else if (t<a+h) then
- begin
- t:= aTot;
- if (t > 0) then
- begin
- FollowGear:= AddGear(0, 0, gtCase, 0, _0, _0, 0);
- t:= GetRandom(t);
- i:= Low(TAmmoType);
- FollowGear^.Pos:= posCaseAmmo;
- FollowGear^.AmmoType:= i;
- AddCaption(GetEventString(eidNewAmmoPack), cWhiteColor, capgrpAmmoInfo);
- end
- end
-else
- begin
- t:= uTot;
- if (t > 0) then
- begin
- FollowGear:= AddGear(0, 0, gtCase, 0, _0, _0, 0);
- t:= GetRandom(t);
- i:= Low(TAmmoType);
- FollowGear^.Pos:= posCaseUtility;
- FollowGear^.AmmoType:= i;
- AddCaption(GetEventString(eidNewUtilityPack), cWhiteColor, capgrpAmmoInfo);
- end
- end;
-
-// handles case of no ammo or utility crates - considered also placing booleans in uAmmos and altering probabilities
-if (FollowGear <> nil) then
- begin
- FindPlace(FollowGear, true, 0, LAND_WIDTH);
-
- if (FollowGear <> nil) then
- AddVoice(sndReinforce, CurrentTeam^.voicepack)
- end
-end;
-
function GearByUID(uid : Longword) : PGear;
var gear: PGear;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hedgewars/uGearsHandlersMess.pas Mon Jul 01 23:23:22 2013 +0300
@@ -0,0 +1,5760 @@
+(*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *)
+
+(*
+ * This file contains the step handlers for gears.
+ *
+ * Important: Since gears change the course of the game, calculations that
+ * lead to different results for different clients/players/machines
+ * should NOT occur!
+ * Use safe functions and data types! (e.g. GetRandom() and hwFloat)
+ *)
+
+ {$INCLUDE "options.inc"}
+
+unit uGearsHandlersMess;
+interface
+uses uTypes, uFloat;
+
+procedure doStepPerPixel(Gear: PGear; step: TGearStepProcedure; onlyCheckIfChanged: boolean);
+procedure makeHogsWorry(x, y: hwFloat; r: LongInt);
+procedure HideHog(HH: PHedgehog);
+procedure doStepDrowningGear(Gear: PGear);
+procedure doStepFallingGear(Gear: PGear);
+procedure doStepBomb(Gear: PGear);
+procedure doStepMolotov(Gear: PGear);
+procedure doStepCluster(Gear: PGear);
+procedure doStepShell(Gear: PGear);
+procedure doStepSnowball(Gear: PGear);
+procedure doStepSnowflake(Gear: PGear);
+procedure doStepGrave(Gear: PGear);
+procedure doStepBeeWork(Gear: PGear);
+procedure doStepBee(Gear: PGear);
+procedure doStepShotIdle(Gear: PGear);
+procedure doStepShotgunShot(Gear: PGear);
+procedure spawnBulletTrail(Bullet: PGear);
+procedure doStepBulletWork(Gear: PGear);
+procedure doStepDEagleShot(Gear: PGear);
+procedure doStepSniperRifleShot(Gear: PGear);
+procedure doStepActionTimer(Gear: PGear);
+procedure doStepPickHammerWork(Gear: PGear);
+procedure doStepPickHammer(Gear: PGear);
+procedure doStepBlowTorchWork(Gear: PGear);
+procedure doStepBlowTorch(Gear: PGear);
+procedure doStepMine(Gear: PGear);
+procedure doStepSMine(Gear: PGear);
+procedure doStepDynamite(Gear: PGear);
+procedure doStepRollingBarrel(Gear: PGear);
+procedure doStepCase(Gear: PGear);
+procedure doStepTarget(Gear: PGear);
+procedure doStepIdle(Gear: PGear);
+procedure doStepShover(Gear: PGear);
+procedure doStepWhip(Gear: PGear);
+procedure doStepFlame(Gear: PGear);
+procedure doStepFirePunchWork(Gear: PGear);
+procedure doStepFirePunch(Gear: PGear);
+procedure doStepParachuteWork(Gear: PGear);
+procedure doStepParachute(Gear: PGear);
+procedure doStepAirAttackWork(Gear: PGear);
+procedure doStepAirAttack(Gear: PGear);
+procedure doStepAirBomb(Gear: PGear);
+procedure doStepGirder(Gear: PGear);
+procedure doStepTeleportAfter(Gear: PGear);
+procedure doStepTeleportAnim(Gear: PGear);
+procedure doStepTeleport(Gear: PGear);
+procedure doStepSwitcherWork(Gear: PGear);
+procedure doStepSwitcher(Gear: PGear);
+procedure doStepMortar(Gear: PGear);
+procedure doStepKamikazeWork(Gear: PGear);
+procedure doStepKamikazeIdle(Gear: PGear);
+procedure doStepKamikaze(Gear: PGear);
+procedure doStepCakeExpl(Gear: PGear);
+procedure doStepCakeDown(Gear: PGear);
+procedure doStepCakeWork(Gear: PGear);
+procedure doStepCakeUp(Gear: PGear);
+procedure doStepCakeFall(Gear: PGear);
+procedure doStepCake(Gear: PGear);
+procedure doStepSeductionWork(Gear: PGear);
+procedure doStepSeductionWear(Gear: PGear);
+procedure doStepSeduction(Gear: PGear);
+procedure doStepWaterUp(Gear: PGear);
+procedure doStepDrillDrilling(Gear: PGear);
+procedure doStepDrill(Gear: PGear);
+procedure doStepBallgunWork(Gear: PGear);
+procedure doStepBallgun(Gear: PGear);
+procedure doStepRCPlaneWork(Gear: PGear);
+procedure doStepRCPlane(Gear: PGear);
+procedure doStepJetpackWork(Gear: PGear);
+procedure doStepJetpack(Gear: PGear);
+procedure doStepBirdyDisappear(Gear: PGear);
+procedure doStepBirdyFly(Gear: PGear);
+procedure doStepBirdyDescend(Gear: PGear);
+procedure doStepBirdyAppear(Gear: PGear);
+procedure doStepBirdy(Gear: PGear);
+procedure doStepEggWork(Gear: PGear);
+procedure doPortalColorSwitch();
+procedure doStepPortal(Gear: PGear);
+procedure loadNewPortalBall(oldPortal: PGear; destroyGear: Boolean);
+procedure doStepMovingPortal_real(Gear: PGear);
+procedure doStepMovingPortal(Gear: PGear);
+procedure doStepPortalShot(newPortal: PGear);
+procedure doStepPiano(Gear: PGear);
+procedure doStepSineGunShotWork(Gear: PGear);
+procedure doStepSineGunShot(Gear: PGear);
+procedure doStepFlamethrowerWork(Gear: PGear);
+procedure doStepFlamethrower(Gear: PGear);
+procedure doStepLandGunWork(Gear: PGear);
+procedure doStepLandGun(Gear: PGear);
+procedure doStepPoisonCloud(Gear: PGear);
+procedure doStepHammer(Gear: PGear);
+procedure doStepHammerHitWork(Gear: PGear);
+procedure doStepHammerHit(Gear: PGear);
+procedure doStepResurrectorWork(Gear: PGear);
+procedure doStepResurrector(Gear: PGear);
+procedure doStepNapalmBomb(Gear: PGear);
+procedure doStepStructure(Gear: PGear);
+procedure doStepTardisWarp(Gear: PGear);
+procedure doStepTardis(Gear: PGear);
+procedure updateFuel(Gear: PGear);
+procedure updateTarget(Gear:PGear; newX, newY:HWFloat);
+procedure doStepIceGun(Gear: PGear);
+procedure doStepAddAmmo(Gear: PGear);
+procedure doStepGenericFaller(Gear: PGear);
+procedure doStepCreeper(Gear: PGear);
+procedure doStepKnife(Gear: PGear);
+
+var
+ upd: Longword;
+ snowLeft,snowRight: LongInt;
+
+implementation
+uses uConsts, uVariables, uVisualGearsList, uRandom, uCollisions, uGearsList, uUtils, uSound
+ , SDLh, uScript, uGearsHedgehog, uGearsUtils, uIO, uCaptions, uLandGraphics
+ , uGearsHandlers, uTextures, uRenderUtils, uAmmos, uTeams, uLandTexture, uCommands
+ , uStore, uAI, uStats;
+
+procedure doStepPerPixel(Gear: PGear; step: TGearStepProcedure; onlyCheckIfChanged: boolean);
+var
+ dX, dY, sX, sY: hwFloat;
+ i, steps: LongWord;
+ caller: TGearStepProcedure;
+begin
+ dX:= Gear^.dX;
+ dY:= Gear^.dY;
+ steps:= max(abs(hwRound(Gear^.X+dX)-hwRound(Gear^.X)), abs(hwRound(Gear^.Y+dY)-hwRound(Gear^.Y)));
+
+ // Gear is still on the same Pixel it was before
+ if steps < 1 then
+ begin
+ if onlyCheckIfChanged then
+ begin
+ Gear^.X := Gear^.X + dX;
+ Gear^.Y := Gear^.Y + dY;
+ EXIT;
+ end
+ else
+ steps := 1;
+ end;
+
+ if steps > 1 then
+ begin
+ sX:= dX / steps;
+ sY:= dY / steps;
+ end
+
+ else
+ begin
+ sX:= dX;
+ sY:= dY;
+ end;
+
+ caller:= Gear^.doStep;
+
+ for i:= 1 to steps do
+ begin
+ Gear^.X := Gear^.X + sX;
+ Gear^.Y := Gear^.Y + sY;
+ step(Gear);
+ if (Gear^.doStep <> caller)
+ or ((Gear^.State and gstCollision) <> 0)
+ or ((Gear^.State and gstMoving) = 0) then
+ break;
+ end;
+end;
+
+procedure makeHogsWorry(x, y: hwFloat; r: LongInt);
+var
+ gi: PGear;
+ d: LongInt;
+begin
+ gi := GearsList;
+ while gi <> nil do
+ begin
+ if (gi^.Kind = gtHedgehog) then
+ begin
+ d := r - hwRound(Distance(gi^.X - x, gi^.Y - y));
+ if (d > 1) and (not gi^.Invulnerable) and (GetRandom(2) = 0) then
+ begin
+ if (CurrentHedgehog^.Gear = gi) then
+ PlaySoundV(sndOops, gi^.Hedgehog^.Team^.voicepack)
+
+ else
+ begin
+ if ((gi^.State and gstMoving) = 0) and (gi^.Hedgehog^.Effects[heFrozen] = 0) then
+ begin
+ gi^.dX.isNegative:= X<gi^.X;
+ gi^.State := gi^.State or gstLoser;
+ end;
+
+ if d > r div 2 then
+ PlaySoundV(sndNooo, gi^.Hedgehog^.Team^.voicepack)
+ else
+ PlaySoundV(sndUhOh, gi^.Hedgehog^.Team^.voicepack);
+ end;
+ end;
+ end;
+
+ gi := gi^.NextGear
+ end;
+end;
+
+procedure HideHog(HH: PHedgehog);
+begin
+ ScriptCall('onHogHide', HH^.Gear^.Uid);
+ DeleteCI(HH^.Gear);
+ if FollowGear = HH^.Gear then
+ FollowGear:= nil;
+
+ if lastGearByUID = HH^.Gear then
+ lastGearByUID := nil;
+
+ HH^.Gear^.Message:= HH^.Gear^.Message or gmRemoveFromList;
+ with HH^.Gear^ do
+ begin
+ Z := cHHZ;
+ HH^.Gear^.Active:= false;
+ State:= State and (not (gstHHDriven or gstAttacking or gstAttacked));
+ Message := Message and (not gmAttack);
+ end;
+ HH^.GearHidden:= HH^.Gear;
+ HH^.Gear:= nil
+end;
+
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepDrowningGear(Gear: PGear);
+ begin
+ AllInactive := false;
+ Gear^.Y := Gear^.Y + cDrownSpeed;
+ Gear^.X := Gear^.X + Gear^.dX * cDrownSpeed;
+ // Create some bubbles (0.5% might be better but causes too few bubbles sometimes)
+ if ((not SuddenDeathDmg and (WaterOpacity < $FF))
+ or (SuddenDeathDmg and (SDWaterOpacity < $FF))) and ((GameTicks and $1F) = 0) then
+ if (Gear^.Kind = gtHedgehog) and (Random(4) = 0) then
+ AddVisualGear(hwRound(Gear^.X) - Gear^.Radius, hwRound(Gear^.Y) - Gear^.Radius, vgtBubble)
+ else if Random(12) = 0 then
+ AddVisualGear(hwRound(Gear^.X) - Gear^.Radius, hwRound(Gear^.Y) - Gear^.Radius, vgtBubble);
+ if (not SuddenDeathDmg and (WaterOpacity > $FE))
+ or (SuddenDeathDmg and (SDWaterOpacity > $FE))
+ or (hwRound(Gear^.Y) > Gear^.Radius + cWaterLine + cVisibleWater) then
+ DeleteGear(Gear);
+ end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepFallingGear(Gear: PGear);
+var
+ isFalling: boolean;
+ //tmp: QWord;
+ tdX, tdY: hwFloat;
+ collV, collH: LongInt;
+ land: word;
+begin
+ // clip velocity at 2 - over 1 per pixel, but really shouldn't cause many actual problems.
+ if Gear^.dX.Round > 2 then
+ Gear^.dX.QWordValue:= 8589934592;
+ if Gear^.dY.Round > 2 then
+ Gear^.dY.QWordValue:= 8589934592;
+
+ if (Gear^.State and gstSubmersible <> 0) and (hwRound(Gear^.Y) > cWaterLine) then
+ begin
+ Gear^.dX:= Gear^.dX * _0_999;
+ Gear^.dY:= Gear^.dY * _0_999
+ end;
+
+ Gear^.State := Gear^.State and (not gstCollision);
+ collV := 0;
+ collH := 0;
+ tdX := Gear^.dX;
+ tdY := Gear^.dY;
+
+
+
+// might need some testing/adjustments - just to avoid projectiles to fly forever (accelerated by wind/skips)
+ if (hwRound(Gear^.X) < min(LAND_WIDTH div -2, -2048))
+ or (hwRound(Gear^.X) > max(LAND_WIDTH * 3 div 2, 6144)) then
+ Gear^.State := Gear^.State or gstCollision;
+
+ if Gear^.dY.isNegative then
+ begin
+ isFalling := true;
+ land:= TestCollisionYwithGear(Gear, -1);
+ if land <> 0 then
+ begin
+ collV := -1;
+ if land and lfIce <> 0 then
+ Gear^.dX := Gear^.dX * (_0_9 + Gear^.Friction * _0_1)
+ else
+ Gear^.dX := Gear^.dX * Gear^.Friction;
+
+ Gear^.dY := - Gear^.dY * Gear^.Elasticity;
+ Gear^.State := Gear^.State or gstCollision
+ end
+ else if (Gear^.AdvBounce=1) and (TestCollisionYwithGear(Gear, 1) <> 0) then
+ collV := 1;
+ end
+ else
+ begin // Gear^.dY.isNegative is false
+ land:= TestCollisionYwithGear(Gear, 1);
+ if land <> 0 then
+ begin
+ collV := 1;
+ isFalling := false;
+ if land and lfIce <> 0 then
+ Gear^.dX := Gear^.dX * (_0_9 + Gear^.Friction * _0_1)
+ else
+ Gear^.dX := Gear^.dX * Gear^.Friction;
+
+ Gear^.dY := - Gear^.dY * Gear^.Elasticity;
+ Gear^.State := Gear^.State or gstCollision
+ end
+ else
+ begin
+ isFalling := true;
+ if (Gear^.AdvBounce=1) and (TestCollisionYwithGear(Gear, -1) <> 0) then
+ collV := -1
+ end
+ end;
+
+
+ if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then
+ begin
+ collH := hwSign(Gear^.dX);
+ Gear^.dX := - Gear^.dX * Gear^.Elasticity;
+ Gear^.dY := Gear^.dY * Gear^.Elasticity;
+ Gear^.State := Gear^.State or gstCollision
+ end
+ else if (Gear^.AdvBounce=1) and TestCollisionXwithGear(Gear, -hwSign(Gear^.dX)) then
+ collH := -hwSign(Gear^.dX);
+ //if Gear^.AdvBounce and (collV <>0) and (collH <> 0) and (hwSqr(tdX) + hwSqr(tdY) > _0_08) then
+ if (Gear^.AdvBounce=1) and (collV <>0) and (collH <> 0) and ((collV=-1)
+ or ((tdX.QWordValue + tdY.QWordValue) > _0_2.QWordValue)) then
+ begin
+ Gear^.dX := tdY*Gear^.Elasticity*Gear^.Friction;
+ Gear^.dY := tdX*Gear^.Elasticity;
+ //*Gear^.Friction;
+ Gear^.dY.isNegative := not tdY.isNegative;
+ isFalling := false;
+ Gear^.AdvBounce := 10;
+ end;
+
+ if Gear^.AdvBounce > 1 then
+ dec(Gear^.AdvBounce);
+
+ if isFalling then
+ begin
+ Gear^.dY := Gear^.dY + cGravity;
+ if (GameFlags and gfMoreWind) <> 0 then
+ Gear^.dX := Gear^.dX + cWindSpeed / Gear^.Density
+ end;
+
+ Gear^.X := Gear^.X + Gear^.dX;
+ Gear^.Y := Gear^.Y + Gear^.dY;
+ if Gear^.Kind <> gtBee then
+ CheckGearDrowning(Gear);
+ //if (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) < _0_0002) and
+ if (not isFalling) and ((Gear^.dX.QWordValue + Gear^.dY.QWordValue) < _0_02.QWordValue) then
+ Gear^.State := Gear^.State and (not gstMoving)
+ else
+ Gear^.State := Gear^.State or gstMoving;
+
+ if (Gear^.nImpactSounds > 0) and
+ (Gear^.State and gstCollision <> 0) and
+ (((Gear^.Kind <> gtMine) and (Gear^.Damage <> 0)) or (Gear^.State and gstMoving <> 0)) and
+ (((Gear^.Radius < 3) and (Gear^.dY < -_0_1)) or
+ ((Gear^.Radius >= 3) and
+ ((Gear^.dX.QWordValue > _0_1.QWordValue) or (Gear^.dY.QWordValue > _0_1.QWordValue)))) then
+ PlaySound(TSound(ord(Gear^.ImpactSound) + LongInt(GetRandom(Gear^.nImpactSounds))), true);
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepBomb(Gear: PGear);
+var
+ i, x, y: LongInt;
+ dX, dY, gdX: hwFloat;
+ vg: PVisualGear;
+begin
+ AllInactive := false;
+
+ doStepFallingGear(Gear);
+
+ dec(Gear^.Timer);
+ if Gear^.Timer = 1000 then // might need adjustments
+ case Gear^.Kind of
+ gtGrenade: makeHogsWorry(Gear^.X, Gear^.Y, 50);
+ gtClusterBomb: makeHogsWorry(Gear^.X, Gear^.Y, 20);
+ gtWatermelon: makeHogsWorry(Gear^.X, Gear^.Y, 75);
+ gtHellishBomb: makeHogsWorry(Gear^.X, Gear^.Y, 90);
+ gtGasBomb: makeHogsWorry(Gear^.X, Gear^.Y, 50);
+ end;
+
+ if (Gear^.Kind = gtBall) and ((Gear^.State and gstTmpFlag) <> 0) then
+ begin
+ CheckCollision(Gear);
+ if (Gear^.State and gstCollision) <> 0 then
+ doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 20, Gear^.Hedgehog, EXPLDontDraw or EXPLNoGfx);
+ end;
+
+ if (Gear^.Kind = gtGasBomb) and ((GameTicks mod 200) = 0) then
+ begin
+ vg:= AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeWhite);
+ if vg <> nil then
+ vg^.Tint:= $FFC0C000;
+ end;
+
+ if Gear^.Timer = 0 then
+ begin
+ case Gear^.Kind of
+ gtGrenade: doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound);
+ gtBall: doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 40, Gear^.Hedgehog, EXPLAutoSound);
+ gtClusterBomb:
+ begin
+ x := hwRound(Gear^.X);
+ y := hwRound(Gear^.Y);
+ gdX:= Gear^.dX;
+ doMakeExplosion(x, y, 20, Gear^.Hedgehog, EXPLAutoSound);
+ for i:= 0 to 4 do
+ begin
+ dX := rndSign(GetRandomf * _0_1) + gdX / 5;
+ dY := (GetRandomf - _3) * _0_08;
+ FollowGear := AddGear(x, y, gtCluster, 0, dX, dY, 25)
+ end
+ end;
+ gtWatermelon:
+ begin
+ x := hwRound(Gear^.X);
+ y := hwRound(Gear^.Y);
+ gdX:= Gear^.dX;
+ doMakeExplosion(x, y, 75, Gear^.Hedgehog, EXPLAutoSound);
+ for i:= 0 to 5 do
+ begin
+ dX := rndSign(GetRandomf * _0_1) + gdX / 5;
+ dY := (GetRandomf - _1_5) * _0_3;
+ FollowGear:= AddGear(x, y, gtMelonPiece, 0, dX, dY, 75);
+ FollowGear^.DirAngle := i * 60
+ end
+ end;
+ gtHellishBomb:
+ begin
+ x := hwRound(Gear^.X);
+ y := hwRound(Gear^.Y);
+ doMakeExplosion(x, y, 90, Gear^.Hedgehog, EXPLAutoSound);
+
+ for i:= 0 to 127 do
+ begin
+ dX := AngleCos(i * 16) * _0_5 * (GetRandomf + _1);
+ dY := AngleSin(i * 16) * _0_5 * (GetRandomf + _1);
+ if i mod 2 = 0 then
+ begin
+ AddGear(x, y, gtFlame, gstTmpFlag, dX, dY, 0);
+ AddGear(x, y, gtFlame, 0, dX, -dY, 0)
+ end
+ else
+ begin
+ AddGear(x, y, gtFlame, 0, dX, dY, 0);
+ AddGear(x, y, gtFlame, gstTmpFlag, dX, -dY, 0)
+ end;
+ end
+ end;
+ gtGasBomb:
+ begin
+ doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 20, Gear^.Hedgehog, EXPLAutoSound);
+ for i:= 0 to 2 do
+ begin
+ x:= GetRandom(60);
+ y:= GetRandom(40);
+ FollowGear:= AddGear(hwRound(Gear^.X) - 30 + x, hwRound(Gear^.Y) - 20 + y, gtPoisonCloud, 0, _0, _0, 0);
+ end
+ end;
+ end;
+ DeleteGear(Gear);
+ exit
+ end;
+
+ CalcRotationDirAngle(Gear);
+
+ if Gear^.Kind = gtHellishBomb then
+ begin
+
+ if Gear^.Timer = 3000 then
+ begin
+ Gear^.nImpactSounds := 0;
+ PlaySound(sndHellish);
+ end;
+
+ if (GameTicks and $3F) = 0 then
+ if (Gear^.State and gstCollision) = 0 then
+ AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtEvilTrace);
+ end;
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepMolotov(Gear: PGear);
+var
+ s: Longword;
+ i, gX, gY: LongInt;
+ dX, dY: hwFloat;
+ smoke, glass: PVisualGear;
+begin
+ AllInactive := false;
+
+ doStepFallingGear(Gear);
+ CalcRotationDirAngle(Gear);
+
+ // let's add some smoke depending on speed
+ s:= max(32,152 - round((abs(hwFloat2FLoat(Gear^.dX))+abs(hwFloat2Float(Gear^.dY)))*120))+random(10);
+ if (GameTicks mod s) = 0 then
+ begin
+ // adjust angle to match the texture
+ if Gear^.dX.isNegative then
+ i:= 130
+ else i:= 50;
+
+ smoke:= AddVisualGear(hwRound(Gear^.X)-round(cos((Gear^.DirAngle+i) * pi / 180)*20), hwRound(Gear^.Y)-round(sin((Gear^.DirAngle+i) * pi / 180)*20), vgtSmoke);
+ if smoke <> nil then
+ smoke^.Scale:= 0.75;
+ end;
+
+ if (Gear^.State and gstCollision) <> 0 then
+ begin
+ PlaySound(sndMolotov);
+ gX := hwRound(Gear^.X);
+ gY := hwRound(Gear^.Y);
+ for i:= 0 to 4 do
+ begin
+ (*glass:= AddVisualGear(gx+random(7)-3, gy+random(5)-2, vgtEgg);
+ if glass <> nil then
+ begin
+ glass^.Frame:= 2;
+ glass^.Tint:= $41B83ED0 - i * $10081000;
+ glass^.dX:= 1/(10*(random(11)-5));
+ glass^.dY:= -1/(random(4)+5);
+ end;*)
+ glass:= AddVisualGear(gx+random(7)-3, gy+random(7)-3, vgtStraightShot);
+ if glass <> nil then
+ with glass^ do
+ begin
+ Frame:= 2;
+ Tint:= $41B83ED0 - i * $10081000;
+ Angle:= random(360);
+ dx:= 0.0000001;
+ dy:= 0;
+ if random(2) = 0 then
+ dx := -dx;
+ FrameTicks:= 750;
+ State:= ord(sprEgg)
+ end;
+ end;
+ for i:= 0 to 24 do
+ begin
+ dX := AngleCos(i * 2) * ((_0_15*(i div 5))) * (GetRandomf + _1);
+ dY := AngleSin(i * 8) * _0_5 * (GetRandomf + _1);
+ AddGear(gX, gY, gtFlame, gstTmpFlag, dX, dY, 0);
+ AddGear(gX, gY, gtFlame, gstTmpFlag, dX,-dY, 0);
+ AddGear(gX, gY, gtFlame, gstTmpFlag,-dX, dY, 0);
+ AddGear(gX, gY, gtFlame, gstTmpFlag,-dX,-dY, 0);
+ end;
+ DeleteGear(Gear);
+ exit
+ end;
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+
+procedure doStepCluster(Gear: PGear);
+begin
+ AllInactive := false;
+ doStepFallingGear(Gear);
+ if (Gear^.State and gstCollision) <> 0 then
+ begin
+ doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Timer, Gear^.Hedgehog, EXPLAutoSound);
+ DeleteGear(Gear);
+ exit
+ end;
+
+ if (Gear^.Kind = gtMelonPiece)
+ or (Gear^.Kind = gtBall) then
+ CalcRotationDirAngle(Gear)
+ else if (GameTicks and $1F) = 0 then
+ begin
+ if hwRound(Gear^.Y) > cWaterLine then
+ AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtBubble)
+ else AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace)
+ end
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepShell(Gear: PGear);
+begin
+ AllInactive := false;
+ if (GameFlags and gfMoreWind) = 0 then
+ Gear^.dX := Gear^.dX + cWindSpeed;
+ doStepFallingGear(Gear);
+ if (Gear^.State and gstCollision) <> 0 then
+ begin
+ doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound);
+ DeleteGear(Gear);
+ exit
+ end;
+ if (GameTicks and $3F) = 0 then
+ begin
+ if hwRound(Gear^.Y) > cWaterLine then
+ AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtBubble)
+ else AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace)
+ end
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepSnowball(Gear: PGear);
+var kick, i: LongInt;
+ particle: PVisualGear;
+ gdX, gdY: hwFloat;
+begin
+ AllInactive := false;
+ if (GameFlags and gfMoreWind) = 0 then
+ Gear^.dX := Gear^.dX + cWindSpeed;
+ gdX := Gear^.dX;
+ gdY := Gear^.dY;
+ doStepFallingGear(Gear);
+ CalcRotationDirAngle(Gear);
+ if (Gear^.State and gstCollision) <> 0 then
+ begin
+ kick:= hwRound((hwAbs(gdX)+hwAbs(gdY)) * _20);
+ Gear^.dX:= gdX;
+ Gear^.dY:= gdY;
+ AmmoShove(Gear, 0, kick);
+ for i:= 15 + kick div 10 downto 0 do
+ begin
+ particle := AddVisualGear(hwRound(Gear^.X) + Random(25), hwRound(Gear^.Y) + Random(25), vgtDust);
+ if particle <> nil then
+ particle^.dX := particle^.dX + (Gear^.dX.QWordValue / 21474836480)
+ end;
+ DeleteGear(Gear);
+ exit
+ end;
+ if ((GameTicks and $1F) = 0) and (Random(3) = 0) then
+ begin
+ particle:= AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtDust);
+ if particle <> nil then
+ particle^.dX := particle^.dX + (Gear^.dX.QWordValue / 21474836480)
+ end
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepSnowflake(Gear: PGear);
+var xx, yy, px, py, rx, ry, lx, ly: LongInt;
+ move, draw, allpx, gun: Boolean;
+ s: PSDL_Surface;
+ p: PLongwordArray;
+ lf: LongWord;
+begin
+inc(Gear^.Pos);
+gun:= (Gear^.State and gstTmpFlag) <> 0;
+move:= false;
+draw:= false;
+if gun then
+ begin
+ Gear^.State:= Gear^.State and (not gstInvisible);
+ doStepFallingGear(Gear);
+ CheckCollision(Gear);
+ if ((Gear^.State and gstCollision) <> 0) or ((Gear^.State and gstMoving) = 0) then
+ draw:= true;
+ xx:= hwRound(Gear^.X);
+ yy:= hwRound(Gear^.Y);
+ end
+else if GameTicks and $7 = 0 then
+ begin
+ with Gear^ do
+ begin
+ State:= State and (not gstInvisible);
+ X:= X + cWindSpeed * 3200 + dX;
+ Y:= Y + dY + cGravity * vobFallSpeed * 8; // using same value as flakes to try and get similar results
+ xx:= hwRound(X);
+ yy:= hwRound(Y);
+ if vobVelocity <> 0 then
+ begin
+ DirAngle := DirAngle + (Damage / 1000);
+ if DirAngle < 0 then
+ DirAngle := DirAngle + 360
+ else if 360 < DirAngle then
+ DirAngle := DirAngle - 360;
+ end;
+(*
+We aren't using frametick right now, so just a waste of cycles.
+ inc(Health, 8);
+ if longword(Health) > vobFrameTicks then
+ begin
+ dec(Health, vobFrameTicks);
+ inc(Timer);
+ if Timer = vobFramesCount then
+ Timer:= 0
+ end;
+*)
+ // move back to cloud layer
+ if yy > cWaterLine then
+ move:= true
+ else if (xx > snowRight) or (xx < snowLeft) then
+ move:=true
+ // Solid pixel encountered
+ else if ((yy and LAND_HEIGHT_MASK) = 0) and ((xx and LAND_WIDTH_MASK) = 0) and (Land[yy, xx] <> 0) then
+ begin
+ lf:= Land[yy, xx] and (lfObject or lfBasic or lfIndestructible);
+ if lf = 0 then lf:= lfObject;
+ // If there's room below keep falling
+ if (((yy-1) and LAND_HEIGHT_MASK) = 0) and (Land[yy-1, xx] = 0) then
+ begin
+ X:= X - cWindSpeed * 1600 - dX;
+ end
+ // If there's room below, on the sides, fill the gaps
+ else if (((yy-1) and LAND_HEIGHT_MASK) = 0) and (((xx-(1*hwSign(cWindSpeed))) and LAND_WIDTH_MASK) = 0) and (Land[yy-1, (xx-(1*hwSign(cWindSpeed)))] = 0) then
+ begin
+ X:= X - _0_8 * hwSign(cWindSpeed);
+ Y:= Y - dY - cGravity * vobFallSpeed * 8;
+ end
+ else if (((yy-1) and LAND_HEIGHT_MASK) = 0) and (((xx-(2*hwSign(cWindSpeed))) and LAND_WIDTH_MASK) = 0) and (Land[yy-1, (xx-(2*hwSign(cWindSpeed)))] = 0) then
+ begin
+ X:= X - _0_8 * 2 * hwSign(cWindSpeed);
+ Y:= Y - dY - cGravity * vobFallSpeed * 8;
+ end
+ else if (((yy-1) and LAND_HEIGHT_MASK) = 0) and (((xx+(1*hwSign(cWindSpeed))) and LAND_WIDTH_MASK) = 0) and (Land[yy-1, (xx+(1*hwSign(cWindSpeed)))] = 0) then
+ begin
+ X:= X + _0_8 * hwSign(cWindSpeed);
+ Y:= Y - dY - cGravity * vobFallSpeed * 8;
+ end
+ else if (((yy-1) and LAND_HEIGHT_MASK) = 0) and (((xx+(2*hwSign(cWindSpeed))) and LAND_WIDTH_MASK) = 0) and (Land[yy-1, (xx+(2*hwSign(cWindSpeed)))] = 0) then
+ begin
+ X:= X + _0_8 * 2 * hwSign(cWindSpeed);
+ Y:= Y - dY - cGravity * vobFallSpeed * 8;
+ end
+ // if there's an hog/object below do nothing
+ else if ((((yy+1) and LAND_HEIGHT_MASK) = 0) and ((Land[yy+1, xx] and $FF) <> 0))
+ then move:=true
+ else draw:= true
+ end
+ end
+ end;
+if draw then
+ with Gear^ do
+ begin
+ // we've collided with land. draw some stuff and get back into the clouds
+ move:= true;
+ if (Pos > 20) and ((CurAmmoGear = nil)
+ or (CurAmmoGear^.Kind <> gtRope)) then
+ begin
+////////////////////////////////// TODO - ASK UNC0RR FOR A GOOD HOME FOR THIS ////////////////////////////////////
+ if not gun then
+ begin
+ dec(yy,3);
+ dec(xx,1)
+ end;
+ s:= SpritesData[sprSnow].Surface;
+ p:= s^.pixels;
+ allpx:= true;
+ for py:= 0 to Pred(s^.h) do
+ begin
+ for px:= 0 to Pred(s^.w) do
+ begin
+ lx:=xx + px; ly:=yy + py;
+ if (ly and LAND_HEIGHT_MASK = 0) and (lx and LAND_WIDTH_MASK = 0) and (Land[ly, lx] and $FF = 0) then
+ begin
+ rx:= lx;
+ ry:= ly;
+ if cReducedQuality and rqBlurryLand <> 0 then
+ begin
+ rx:= rx div 2;ry:= ry div 2;
+ end;
+ if Land[yy + py, xx + px] <= lfAllObjMask then
+ if gun then
+ begin
+ LandDirty[yy div 32, xx div 32]:= 1;
+ if LandPixels[ry, rx] = 0 then
+ Land[ly, lx]:= lfDamaged or lfObject
+ else Land[ly, lx]:= lfDamaged or lfBasic
+ end
+ else Land[ly, lx]:= lf;
+ if gun then
+ LandPixels[ry, rx]:= (ExplosionBorderColor and (not AMask)) or (p^[px] and AMask)
+ else LandPixels[ry, rx]:= addBgColor(LandPixels[ry, rx], p^[px]);
+ end
+ else allpx:= false
+ end;
+ p:= @(p^[s^.pitch shr 2])
+ end;
+
+ // Why is this here. For one thing, there's no test on +1 being safe.
+ //Land[py, px+1]:= lfBasic;
+
+ if allpx then
+ UpdateLandTexture(xx, Pred(s^.h), yy, Pred(s^.w), true)
+ else
+ begin
+ UpdateLandTexture(
+ max(0, min(LAND_WIDTH, xx)),
+ min(LAND_WIDTH - xx, Pred(s^.w)),
+ max(0, min(LAND_WIDTH, yy)),
+ min(LAND_HEIGHT - yy, Pred(s^.h)), false // could this be true without unnecessarily creating blanks?
+ );
+ end;
+////////////////////////////////// TODO - ASK UNC0RR FOR A GOOD HOME FOR THIS ////////////////////////////////////
+ end
+ end;
+
+if move then
+ begin
+ if gun then
+ begin
+ DeleteGear(Gear);
+ exit
+ end;
+ Gear^.Pos:= 0;
+ Gear^.X:= int2hwFloat(LongInt(GetRandom(snowRight - snowLeft)) + snowLeft);
+ Gear^.Y:= int2hwFloat(LAND_HEIGHT + LongInt(GetRandom(50)) - 1325);
+ Gear^.State:= Gear^.State or gstInvisible;
+ end
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepGrave(Gear: PGear);
+begin
+ if (Gear^.Message and gmDestroy) <> 0 then
+ begin
+ DeleteGear(Gear);
+ exit
+ end;
+
+ AllInactive := false;
+
+ if Gear^.dY.isNegative then
+ if TestCollisionY(Gear, -1) then
+ Gear^.dY := _0;
+
+ if not Gear^.dY.isNegative then
+ if TestCollisionY(Gear, 1) then
+ begin
+ Gear^.dY := - Gear^.dY * Gear^.Elasticity;
+ if Gear^.dY > - _1div1024 then
+ begin
+ Gear^.Active := false;
+ exit
+ end
+ else if Gear^.dY < - _0_03 then
+ PlaySound(Gear^.ImpactSound)
+ end;
+
+ Gear^.Y := Gear^.Y + Gear^.dY;
+ CheckGearDrowning(Gear);
+ Gear^.dY := Gear^.dY + cGravity
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepBeeWork(Gear: PGear);
+var
+ t: hwFloat;
+ gX,gY,i: LongInt;
+ uw, nuw: boolean;
+ flower: PVisualGear;
+
+begin
+ AllInactive := false;
+ gX := hwRound(Gear^.X);
+ gY := hwRound(Gear^.Y);
+ uw := (Gear^.Tag <> 0); // was bee underwater last tick?
+ nuw := (cWaterLine < gy + Gear^.Radius); // is bee underwater now?
+
+ // if water entered or left
+ if nuw <> uw then
+ begin
+ AddVisualGear(gX, cWaterLine, vgtSplash);
+ AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet);
+ AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet);
+ AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet);
+ AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet);
+ StopSoundChan(Gear^.SoundChannel);
+ if nuw then
+ begin
+ Gear^.SoundChannel := LoopSound(sndBeeWater);
+ Gear^.Tag := 1;
+ end
+ else
+ begin
+ Gear^.SoundChannel := LoopSound(sndBee);
+ Gear^.Tag := 0;
+ end;
+ end;
+
+
+ if Gear^.Timer = 0 then
+ Gear^.RenderTimer:= false
+ else
+ begin
+ if (GameTicks and $F) = 0 then
+ begin
+ if (GameTicks and $30) = 0 then
+ AddVisualGear(gX, gY, vgtBeeTrace);
+ Gear^.dX := Gear^.Elasticity * (Gear^.dX + _0_000064 * (Gear^.Target.X - gX));
+ Gear^.dY := Gear^.Elasticity * (Gear^.dY + _0_000064 * (Gear^.Target.Y - gY));
+ // make sure new speed isn't higher than original one (which we stored in Friction variable)
+ t := Gear^.Friction / Distance(Gear^.dX, Gear^.dY);
+ Gear^.dX := Gear^.dX * t;
+ Gear^.dY := Gear^.dY * t;
+ end;
+
+ Gear^.X := Gear^.X + Gear^.dX;
+ Gear^.Y := Gear^.Y + Gear^.dY;
+
+ end;
+
+
+ CheckCollision(Gear);
+ if ((Gear^.State and gstCollision) <> 0) then
+ begin
+ StopSoundChan(Gear^.SoundChannel);
+ doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound);
+ for i:= 0 to 31 do
+ begin
+ flower:= AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtStraightShot);
+ if flower <> nil then
+ with flower^ do
+ begin
+ Scale:= 0.75;
+ dx:= 0.001 * (random(200));
+ dy:= 0.001 * (random(200));
+ if random(2) = 0 then
+ dx := -dx;
+ if random(2) = 0 then
+ dy := -dy;
+ FrameTicks:= random(250) + 250;
+ State:= ord(sprTargetBee);
+ end;
+ end;
+ DeleteGear(Gear);
+ end;
+
+ if (Gear^.Timer > 0) then
+ dec(Gear^.Timer)
+ else
+ begin
+ if nuw then
+ begin
+ StopSoundChan(Gear^.SoundChannel);
+ CheckGearDrowning(Gear);
+ end
+ else
+ doStepFallingGear(Gear);
+ end;
+end;
+
+procedure doStepBee(Gear: PGear);
+begin
+ AllInactive := false;
+ Gear^.X := Gear^.X + Gear^.dX;
+ Gear^.Y := Gear^.Y + Gear^.dY;
+ Gear^.dY := Gear^.dY + cGravity;
+ CheckCollision(Gear);
+ if (Gear^.State and gstCollision) <> 0 then
+ begin
+ doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound);
+ DeleteGear(Gear);
+ exit
+ end;
+ dec(Gear^.Timer);
+ if Gear^.Timer = 0 then
+ begin
+ Gear^.Hedgehog^.Gear^.Message:= Gear^.Hedgehog^.Gear^.Message and (not gmAttack);
+ Gear^.Hedgehog^.Gear^.State:= Gear^.Hedgehog^.Gear^.State and (not gstAttacking);
+ AttackBar:= 0;
+
+ Gear^.SoundChannel := LoopSound(sndBee);
+ Gear^.Timer := 5000;
+ // save initial speed in otherwise unused Friction variable
+ Gear^.Friction := Distance(Gear^.dX, Gear^.dY);
+ Gear^.doStep := @doStepBeeWork
+ end;
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepShotIdle(Gear: PGear);
+begin
+ AllInactive := false;
+ inc(Gear^.Timer);
+ if Gear^.Timer > 75 then
+ begin
+ DeleteGear(Gear);
+ AfterAttack
+ end
+end;
+
+procedure doStepShotgunShot(Gear: PGear);
+var
+ i: LongWord;
+ shell: PVisualGear;
+begin
+ AllInactive := false;
+
+ if ((Gear^.State and gstAnimation) = 0) then
+ begin
+ dec(Gear^.Timer);
+ if Gear^.Timer = 0 then
+ begin
+ PlaySound(sndShotgunFire);
+ shell := AddVisualGear(hwRound(Gear^.x), hwRound(Gear^.y), vgtShell);
+ if shell <> nil then
+ begin
+ shell^.dX := gear^.dX.QWordValue / -17179869184;
+ shell^.dY := gear^.dY.QWordValue / -17179869184;
+ shell^.Frame := 0
+ end;
+ Gear^.State := Gear^.State or gstAnimation
+ end;
+ exit
+ end else
+ if(Gear^.Hedgehog^.Gear = nil) or ((Gear^.Hedgehog^.Gear^.State and gstMoving) <> 0) then
+ begin
+ DeleteGear(Gear);
+ AfterAttack;
+ exit
+ end
+ else
+ inc(Gear^.Timer);
+
+ i := 200;
+ repeat
+ Gear^.X := Gear^.X + Gear^.dX;
+ Gear^.Y := Gear^.Y + Gear^.dY;
+ CheckCollision(Gear);
+ if (Gear^.State and gstCollision) <> 0 then
+ begin
+ Gear^.X := Gear^.X + Gear^.dX * 8;
+ Gear^.Y := Gear^.Y + Gear^.dY * 8;
+ ShotgunShot(Gear);
+ Gear^.doStep := @doStepShotIdle;
+ exit
+ end;
+
+ CheckGearDrowning(Gear);
+ if (Gear^.State and gstDrowning) <> 0 then
+ begin
+ Gear^.doStep := @doStepShotIdle;
+ exit
+ end;
+ dec(i)
+ until i = 0;
+ if (hwRound(Gear^.X) and LAND_WIDTH_MASK <> 0) or (hwRound(Gear^.Y) and LAND_HEIGHT_MASK <> 0) then
+ Gear^.doStep := @doStepShotIdle
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure spawnBulletTrail(Bullet: PGear);
+var oX, oY: hwFloat;
+ VGear: PVisualGear;
+begin
+ if Bullet^.PortalCounter = 0 then
+ begin
+ ox:= CurrentHedgehog^.Gear^.X + Int2hwFloat(GetLaunchX(CurrentHedgehog^.CurAmmoType, hwSign(CurrentHedgehog^.Gear^.dX), CurrentHedgehog^.Gear^.Angle));
+ oy:= CurrentHedgehog^.Gear^.Y + Int2hwFloat(GetLaunchY(CurrentHedgehog^.CurAmmoType, CurrentHedgehog^.Gear^.Angle));
+ end
+ else
+ begin
+ ox:= Bullet^.Elasticity;
+ oy:= Bullet^.Friction;
+ end;
+
+ // Bullet trail
+ VGear := AddVisualGear(hwRound(ox), hwRound(oy), vgtLineTrail);
+
+ if VGear <> nil then
+ begin
+ VGear^.X:= hwFloat2Float(ox);
+ VGear^.Y:= hwFloat2Float(oy);
+ VGear^.dX:= hwFloat2Float(Bullet^.X);
+ VGear^.dY:= hwFloat2Float(Bullet^.Y);
+
+ // reached edge of land. assume infinite beam. Extend it way out past camera
+ if (hwRound(Bullet^.X) and LAND_WIDTH_MASK <> 0)
+ or (hwRound(Bullet^.Y) and LAND_HEIGHT_MASK <> 0) then
+ // only extend if not under water
+ if hwRound(Bullet^.Y) < cWaterLine then
+ begin
+ VGear^.dX := VGear^.dX + max(LAND_WIDTH,4096) * (VGear^.dX - VGear^.X);
+ VGear^.dY := VGear^.dY + max(LAND_WIDTH,4096) * (VGear^.dY - VGear^.Y);
+ end;
+
+ VGear^.Timer := 200;
+ end;
+end;
+
+procedure doStepBulletWork(Gear: PGear);
+var
+ i, x, y: LongWord;
+ oX, oY: hwFloat;
+ VGear: PVisualGear;
+begin
+ AllInactive := false;
+ inc(Gear^.Timer);
+ i := 80;
+ oX := Gear^.X;
+ oY := Gear^.Y;
+ repeat
+ Gear^.X := Gear^.X + Gear^.dX;
+ Gear^.Y := Gear^.Y + Gear^.dY;
+ x := hwRound(Gear^.X);
+ y := hwRound(Gear^.Y);
+
+ if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) and (Land[y, x] <> 0) then
+ inc(Gear^.Damage);
+ // let's interrupt before a collision to give portals a chance to catch the bullet
+ if (Gear^.Damage = 1) and (Gear^.Tag = 0) and not(CheckLandValue(x, y, lfLandMask)) then
+ begin
+ Gear^.Tag := 1;
+ Gear^.Damage := 0;
+ Gear^.X := Gear^.X - Gear^.dX;
+ Gear^.Y := Gear^.Y - Gear^.dY;
+ CheckGearDrowning(Gear);
+ break;
+ end
+ else
+ Gear^.Tag := 0;
+
+ if Gear^.Damage > 5 then
+ if Gear^.AmmoType = amDEagle then
+ AmmoShove(Gear, 7, 20)
+ else
+ AmmoShove(Gear, Gear^.Timer, 20);
+ CheckGearDrowning(Gear);
+ dec(i)
+ until (i = 0) or (Gear^.Damage > Gear^.Health) or ((Gear^.State and gstDrowning) <> 0);
+
+ if Gear^.Damage > 0 then
+ begin
+ DrawTunnel(oX, oY, Gear^.dX, Gear^.dY, 82 - i, 1);
+ dec(Gear^.Health, Gear^.Damage);
+ Gear^.Damage := 0
+ end;
+ if ((Gear^.State and gstDrowning) <> 0) and (Gear^.Damage < Gear^.Health) and ((not SuddenDeathDmg and (WaterOpacity < $FF)) or (SuddenDeathDmg and (SDWaterOpacity < $FF))) then
+ begin
+ for i:=(Gear^.Health - Gear^.Damage) * 4 downto 0 do
+ begin
+ if Random(6) = 0 then
+ AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtBubble);
+ Gear^.X := Gear^.X + Gear^.dX;
+ Gear^.Y := Gear^.Y + Gear^.dY;
+ end;
+ end;
+
+ if (Gear^.Health <= 0)
+ or (hwRound(Gear^.X) and LAND_WIDTH_MASK <> 0)
+ or (hwRound(Gear^.Y) and LAND_HEIGHT_MASK <> 0) then
+ begin
+ if (Gear^.Kind = gtSniperRifleShot) and ((GameFlags and gfLaserSight) = 0) then
+ cLaserSighting := false;
+ if (Ammoz[Gear^.AmmoType].Ammo.NumPerTurn <= CurrentHedgehog^.MultiShootAttacks) and ((GameFlags and gfArtillery) = 0) then
+ cArtillery := false;
+
+ // Bullet Hit
+ if (hwRound(Gear^.X) and LAND_WIDTH_MASK = 0) and (hwRound(Gear^.Y) and LAND_HEIGHT_MASK = 0) then
+ begin
+ VGear := AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtBulletHit);
+ if VGear <> nil then
+ begin
+ VGear^.Angle := DxDy2Angle(-Gear^.dX, Gear^.dY);
+ end;
+ end;
+
+ spawnBulletTrail(Gear);
+ Gear^.doStep := @doStepShotIdle
+ end;
+end;
+
+procedure doStepDEagleShot(Gear: PGear);
+begin
+ PlaySound(sndGun);
+ // add 3 initial steps to avoid problem with ammoshove related to calculation of radius + 1 radius as gear widths, and also just plain old weird angles
+ Gear^.X := Gear^.X + Gear^.dX * 3;
+ Gear^.Y := Gear^.Y + Gear^.dY * 3;
+ Gear^.doStep := @doStepBulletWork
+end;
+
+procedure doStepSniperRifleShot(Gear: PGear);
+var
+ HHGear: PGear;
+ shell: PVisualGear;
+begin
+ cArtillery := true;
+ HHGear := Gear^.Hedgehog^.Gear;
+ HHGear^.State := HHGear^.State or gstNotKickable;
+ HedgehogChAngle(HHGear);
+ if not cLaserSighting then
+ // game does not have default laser sight. turn it on and give them a chance to aim
+ begin
+ cLaserSighting := true;
+ HHGear^.Message := 0;
+ if (HHGear^.Angle >= 32) then
+ dec(HHGear^.Angle,32)
+ end;
+
+ if (HHGear^.Message and gmAttack) <> 0 then
+ begin
+ shell := AddVisualGear(hwRound(Gear^.x), hwRound(Gear^.y), vgtShell);
+ if shell <> nil then
+ begin
+ shell^.dX := gear^.dX.QWordValue / -8589934592;
+ shell^.dY := gear^.dY.QWordValue / -8589934592;
+ shell^.Frame := 1
+ end;
+ Gear^.State := Gear^.State or gstAnimation;
+ Gear^.dX := SignAs(AngleSin(HHGear^.Angle), HHGear^.dX) * _0_5;
+ Gear^.dY := -AngleCos(HHGear^.Angle) * _0_5;
+ PlaySound(sndGun);
+ // add 3 initial steps to avoid problem with ammoshove related to calculation of radius + 1 radius as gear widths, and also just weird angles
+ Gear^.X := Gear^.X + Gear^.dX * 3;
+ Gear^.Y := Gear^.Y + Gear^.dY * 3;
+ Gear^.doStep := @doStepBulletWork;
+ end
+ else
+ if (GameTicks mod 32) = 0 then
+ if (GameTicks mod 4096) < 2048 then
+ begin
+ if (HHGear^.Angle + 1 <= cMaxAngle) then
+ inc(HHGear^.Angle)
+ end
+ else
+ if (HHGear^.Angle >= 1) then
+ dec(HHGear^.Angle);
+
+ if (TurnTimeLeft > 0) then
+ dec(TurnTimeLeft)
+ else
+ begin
+ DeleteGear(Gear);
+ AfterAttack
+ end;
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepActionTimer(Gear: PGear);
+begin
+dec(Gear^.Timer);
+case Gear^.Kind of
+ gtATStartGame:
+ begin
+ AllInactive := false;
+ if Gear^.Timer = 0 then
+ begin
+ AddCaption(trmsg[sidStartFight], cWhiteColor, capgrpGameState);
+ end
+ end;
+ gtATFinishGame:
+ begin
+ AllInactive := false;
+ if Gear^.Timer = 1000 then
+ begin
+ ScreenFade := sfToBlack;
+ ScreenFadeValue := 0;
+ ScreenFadeSpeed := 1;
+ end;
+ if Gear^.Timer = 0 then
+ begin
+ SendIPC(_S'N');
+ SendIPC(_S'q');
+ GameState := gsExit
+ end
+ end;
+ end;
+if Gear^.Timer = 0 then
+ DeleteGear(Gear)
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepPickHammerWork(Gear: PGear);
+var
+ i, ei, x, y: LongInt;
+ HHGear: PGear;
+begin
+ AllInactive := false;
+ HHGear := Gear^.Hedgehog^.Gear;
+ dec(Gear^.Timer);
+ if ((GameFlags and gfInfAttack) <> 0) and (TurnTimeLeft > 0) then
+ dec(TurnTimeLeft);
+ if (TurnTimeLeft = 0) or (Gear^.Timer = 0)
+ or((Gear^.Message and gmDestroy) <> 0)
+ or((HHGear^.State and gstHHDriven) =0) then
+ begin
+ StopSoundChan(Gear^.SoundChannel);
+ DeleteGear(Gear);
+ AfterAttack;
+ doStepHedgehogMoving(HHGear); // for gfInfAttack
+ exit
+ end;
+
+ x:= hwRound(Gear^.X);
+ y:= hwRound(Gear^.Y);
+ if (Gear^.Timer mod 33) = 0 then
+ begin
+ HHGear^.State := HHGear^.State or gstNoDamage;
+ doMakeExplosion(x, y + 7, 6, Gear^.Hedgehog, EXPLDontDraw);
+ HHGear^.State := HHGear^.State and (not gstNoDamage)
+ end;
+
+ if (Gear^.Timer mod 47) = 0 then
+ begin
+ // ok. this was an attempt to turn off dust if not actually drilling land. I have no idea why it isn't working as expected
+ if (( (y + 12) and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) and (Land[y + 12, x] > 255) then
+ for i:= 0 to 1 do
+ AddVisualGear(x - 5 + Random(10), y + 12, vgtDust);
+
+ i := x - Gear^.Radius - LongInt(GetRandom(2));
+ ei := x + Gear^.Radius + LongInt(GetRandom(2));
+ while i <= ei do
+ begin
+ DrawExplosion(i, y + 3, 3);
+ inc(i, 1)
+ end;
+
+ if CheckLandValue(hwRound(Gear^.X + Gear^.dX + SignAs(_6,Gear^.dX)), hwRound(Gear^.Y + _1_9), lfIndestructible) then
+ begin
+ Gear^.X := Gear^.X + Gear^.dX;
+ Gear^.Y := Gear^.Y + _1_9;
+ end;
+ SetAllHHToActive;
+ end;
+ if TestCollisionYwithGear(Gear, 1) <> 0 then
+ begin
+ Gear^.dY := _0;
+ SetLittle(HHGear^.dX);
+ HHGear^.dY := _0;
+ end
+ else
+ begin
+ if CheckLandValue(hwRound(Gear^.X), hwRound(Gear^.Y + Gear^.dY + cGravity), lfLandMask) then
+ begin
+ Gear^.dY := Gear^.dY + cGravity;
+ Gear^.Y := Gear^.Y + Gear^.dY
+ end;
+ if hwRound(Gear^.Y) > cWaterLine then
+ Gear^.Timer := 1
+ end;
+
+ Gear^.X := Gear^.X + HHGear^.dX;
+ if CheckLandValue(hwRound(Gear^.X), hwRound(Gear^.Y)-cHHRadius, lfLandMask) then
+ begin
+ HHGear^.X := Gear^.X;
+ HHGear^.Y := Gear^.Y - int2hwFloat(cHHRadius)
+ end;
+
+ if (Gear^.Message and gmAttack) <> 0 then
+ if (Gear^.State and gsttmpFlag) <> 0 then
+ Gear^.Timer := 1
+ else //there would be a mistake.
+ else
+ if (Gear^.State and gsttmpFlag) = 0 then
+ Gear^.State := Gear^.State or gsttmpFlag;
+ if ((Gear^.Message and gmLeft) <> 0) then
+ Gear^.dX := - _0_3
+ else
+ if ((Gear^.Message and gmRight) <> 0) then
+ Gear^.dX := _0_3
+ else Gear^.dX := _0;
+end;
+
+procedure doStepPickHammer(Gear: PGear);
+var
+ i, y: LongInt;
+ ar: TRangeArray;
+ HHGear: PGear;
+begin
+ i := 0;
+ HHGear := Gear^.Hedgehog^.Gear;
+
+ y := hwRound(Gear^.Y) - cHHRadius * 2;
+ while y < hwRound(Gear^.Y) do
+ begin
+ ar[i].Left := hwRound(Gear^.X) - Gear^.Radius - LongInt(GetRandom(2));
+ ar[i].Right := hwRound(Gear^.X) + Gear^.Radius + LongInt(GetRandom(2));
+ inc(y, 2);
+ inc(i)
+ end;
+
+ DrawHLinesExplosions(@ar, 3, hwRound(Gear^.Y) - cHHRadius * 2, 2, Pred(i));
+ Gear^.dY := HHGear^.dY;
+ DeleteCI(HHGear);
+
+ Gear^.SoundChannel := LoopSound(sndPickhammer);
+ doStepPickHammerWork(Gear);
+ Gear^.doStep := @doStepPickHammerWork
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+var
+ BTPrevAngle, BTSteps: LongInt;
+
+procedure doStepBlowTorchWork(Gear: PGear);
+var
+ HHGear: PGear;
+ b: boolean;
+ prevX: LongInt;
+begin
+ AllInactive := false;
+ dec(Gear^.Timer);
+ if ((GameFlags and gfInfAttack) <> 0) and (TurnTimeLeft > 0) then
+ dec(TurnTimeLeft);
+
+ HHGear := Gear^.Hedgehog^.Gear;
+
+ HedgehogChAngle(HHGear);
+
+ b := false;
+
+ if abs(LongInt(HHGear^.Angle) - BTPrevAngle) > 7 then
+ begin
+ Gear^.dX := SignAs(AngleSin(HHGear^.Angle) * _0_5, Gear^.dX);
+ Gear^.dY := AngleCos(HHGear^.Angle) * ( - _0_5);
+ BTPrevAngle := HHGear^.Angle;
+ b := true
+ end;
+
+ if ((HHGear^.State and gstMoving) <> 0) then
+ begin
+ doStepHedgehogMoving(HHGear);
+ if (HHGear^.State and gstHHDriven) = 0 then
+ Gear^.Timer := 0
+ end;
+
+ if Gear^.Timer mod cHHStepTicks = 0 then
+ begin
+ b := true;
+ if Gear^.dX.isNegative then
+ HHGear^.Message := (HHGear^.Message and (gmAttack or gmUp or gmDown)) or gmLeft
+ else
+ HHGear^.Message := (HHGear^.Message and (gmAttack or gmUp or gmDown)) or gmRight;
+
+ if ((HHGear^.State and gstMoving) = 0) then
+ begin
+ HHGear^.State := HHGear^.State and (not gstAttacking);
+ prevX := hwRound(HHGear^.X);
+
+ // why the call to HedgehogStep then a further increment of X?
+ if (prevX = hwRound(HHGear^.X)) and
+ CheckLandValue(hwRound(HHGear^.X + SignAs(_6, HHGear^.dX)), hwRound(HHGear^.Y),
+ lfIndestructible) then HedgehogStep(HHGear);
+
+ if (prevX = hwRound(HHGear^.X)) and
+ CheckLandValue(hwRound(HHGear^.X + SignAs(_6, HHGear^.dX)), hwRound(HHGear^.Y),
+ lfIndestructible) then HHGear^.X := HHGear^.X + SignAs(_1, HHGear^.dX);
+ HHGear^.State := HHGear^.State or gstAttacking
+ end;
+
+ inc(BTSteps);
+ if BTSteps = 7 then
+ begin
+ BTSteps := 0;
+ if CheckLandValue(hwRound(HHGear^.X + Gear^.dX * (cHHRadius + cBlowTorchC) + SignAs(_6,Gear^.dX)), hwRound(HHGear^.Y + Gear^.dY * (cHHRadius + cBlowTorchC)),lfIndestructible) then
+ begin
+ Gear^.X := HHGear^.X + Gear^.dX * (cHHRadius + cBlowTorchC);
+ Gear^.Y := HHGear^.Y + Gear^.dY * (cHHRadius + cBlowTorchC);
+ end;
+ HHGear^.State := HHGear^.State or gstNoDamage;
+ AmmoShove(Gear, 2, 15);
+ HHGear^.State := HHGear^.State and (not gstNoDamage)
+ end;
+ end;
+
+ if b then
+ begin
+ DrawTunnel(HHGear^.X + Gear^.dX * cHHRadius,
+ HHGear^.Y + Gear^.dY * cHHRadius - _1 -
+ ((hwAbs(Gear^.dX) / (hwAbs(Gear^.dX) + hwAbs(Gear^.dY))) * _0_5 * 7),
+ Gear^.dX, Gear^.dY,
+ cHHStepTicks, cHHRadius * 2 + 7);
+ end;
+
+ if (TurnTimeLeft = 0) or (Gear^.Timer = 0)
+ or ((HHGear^.Message and gmAttack) <> 0) then
+ begin
+ HHGear^.Message := 0;
+ HHGear^.State := HHGear^.State and (not gstNotKickable);
+ DeleteGear(Gear);
+ AfterAttack
+ end
+end;
+
+procedure doStepBlowTorch(Gear: PGear);
+var
+ HHGear: PGear;
+begin
+ BTPrevAngle := High(LongInt);
+ BTSteps := 0;
+ HHGear := Gear^.Hedgehog^.Gear;
+ HedgehogChAngle(HHGear);
+ Gear^.dX := SignAs(AngleSin(HHGear^.Angle) * _0_5, Gear^.dX);
+ Gear^.dY := AngleCos(HHGear^.Angle) * ( - _0_5);
+ DrawTunnel(HHGear^.X,
+ HHGear^.Y + Gear^.dY * cHHRadius - _1 -
+ ((hwAbs(Gear^.dX) / (hwAbs(Gear^.dX) + hwAbs(Gear^.dY))) * _0_5 * 7),
+ Gear^.dX, Gear^.dY,
+ cHHStepTicks, cHHRadius * 2 + 7);
+ HHGear^.Message := 0;
+ HHGear^.State := HHGear^.State or gstNotKickable;
+ Gear^.doStep := @doStepBlowTorchWork
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepMine(Gear: PGear);
+var vg: PVisualGear;
+ dxdy: hwFloat;
+begin
+ if Gear^.Health = 0 then dxdy:= hwAbs(Gear^.dX)+hwAbs(Gear^.dY);
+ if (Gear^.State and gstMoving) <> 0 then
+ begin
+ DeleteCI(Gear);
+ doStepFallingGear(Gear);
+ if (Gear^.State and gstMoving) = 0 then
+ begin
+ AddCI(Gear);
+ Gear^.dX := _0;
+ Gear^.dY := _0
+ end;
+ CalcRotationDirAngle(Gear);
+ AllInactive := false
+ end
+ else if (GameTicks and $3F) = 25 then
+ doStepFallingGear(Gear);
+ if (Gear^.Health = 0) then
+ begin
+ if (dxdy > _0_4) and (Gear^.State and gstCollision <> 0) then
+ inc(Gear^.Damage, hwRound(dxdy * _50));
+
+ if ((GameTicks and $FF) = 0) and (Gear^.Damage > random(30)) then
+ begin
+ vg:= AddVisualGear(hwRound(Gear^.X) - 4 + Random(8), hwRound(Gear^.Y) - 4 - Random(4), vgtSmoke);
+ if vg <> nil then
+ vg^.Scale:= 0.5
+ end;
+
+ if (Gear^.Damage > 35) then
+ begin
+ doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound);
+ DeleteGear(Gear);
+ exit
+ end
+ end;
+
+ if ((Gear^.State and gsttmpFlag) <> 0) and (Gear^.Health <> 0) then
+ if ((Gear^.State and gstAttacking) = 0) then
+ begin
+ if ((GameTicks and $1F) = 0) then
+ if CheckGearNear(Gear, gtHedgehog, 46, 32) <> nil then
+ Gear^.State := Gear^.State or gstAttacking
+ end
+ else // gstAttacking <> 0
+ begin
+ AllInactive := false;
+ if (Gear^.Timer and $FF) = 0 then
+ PlaySound(sndMineTick);
+ if Gear^.Timer = 0 then
+ begin
+ if ((Gear^.State and gstWait) <> 0)
+ or (cMineDudPercent = 0)
+ or (getRandom(100) > cMineDudPercent) then
+ begin
+ doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound);
+ DeleteGear(Gear)
+ end
+ else
+ begin
+ vg:= AddVisualGear(hwRound(Gear^.X) - 4 + Random(8), hwRound(Gear^.Y) - 4 - Random(4), vgtSmoke);
+ if vg <> nil then
+ vg^.Scale:= 0.5;
+ PlaySound(sndVaporize);
+ Gear^.Health := 0;
+ Gear^.Damage := 0;
+ Gear^.State := Gear^.State and (not gstAttacking)
+ end;
+ exit
+ end;
+ dec(Gear^.Timer);
+ end
+ else // gsttmpFlag = 0
+ if (TurnTimeLeft = 0)
+ or ((GameFlags and gfInfAttack <> 0) and (GameTicks > Gear^.FlightTime))
+ or (Gear^.Hedgehog^.Gear = nil) then
+ Gear^.State := Gear^.State or gsttmpFlag;
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepSMine(Gear: PGear);
+begin
+ // TODO: do real calculation?
+ if TestCollisionXwithGear(Gear, 2)
+ or (TestCollisionYwithGear(Gear, -2) <> 0)
+ or TestCollisionXwithGear(Gear, -2)
+ or (TestCollisionYwithGear(Gear, 2) <> 0) then
+ begin
+ if (not isZero(Gear^.dX)) or (not isZero(Gear^.dY)) then
+ begin
+ PlaySound(sndRopeAttach);
+ Gear^.dX:= _0;
+ Gear^.dY:= _0;
+ AddCI(Gear);
+ end;
+ end
+ else
+ begin
+ DeleteCI(Gear);
+ doStepFallingGear(Gear);
+ AllInactive := false;
+ CalcRotationDirAngle(Gear);
+ end;
+
+ if ((Gear^.State and gsttmpFlag) <> 0) and (Gear^.Health <> 0) then
+ begin
+ if ((Gear^.State and gstAttacking) = 0) then
+ begin
+ if ((GameTicks and $1F) = 0) then
+ if CheckGearNear(Gear, gtHedgehog, 46, 32) <> nil then
+ Gear^.State := Gear^.State or gstAttacking
+ end
+ else // gstAttacking <> 0
+ begin
+ AllInactive := false;
+ if Gear^.Timer = 0 then
+ begin
+ doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, Gear^.Hedgehog, EXPLAutoSound);
+ DeleteGear(Gear);
+ exit
+ end else
+ if (Gear^.Timer and $FF) = 0 then
+ PlaySound(sndMineTick);
+
+ dec(Gear^.Timer);
+ end
+ end
+ else // gsttmpFlag = 0
+ if (TurnTimeLeft = 0)
+ or ((GameFlags and gfInfAttack <> 0) and (GameTicks > Gear^.FlightTime))
+ or (Gear^.Hedgehog^.Gear = nil) then
+ Gear^.State := Gear^.State or gsttmpFlag;
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepDynamite(Gear: PGear);
+begin
+ doStepFallingGear(Gear);
+ AllInactive := false;
+ if Gear^.Timer mod 166 = 0 then
+ inc(Gear^.Tag);
+ if Gear^.Timer = 1000 then // might need better timing
+ makeHogsWorry(Gear^.X, Gear^.Y, 75);
+ if Gear^.Timer = 0 then
+ begin
+ doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 75, Gear^.Hedgehog, EXPLAutoSound);
+ DeleteGear(Gear);
+ exit
+ end;
+ dec(Gear^.Timer);
+end;
+
+///////////////////////////////////////////////////////////////////////////////
+
+procedure doStepRollingBarrel(Gear: PGear);
+var
+ i: LongInt;
+ particle: PVisualGear;
+ dxdy: hwFloat;
+begin
+ if (Gear^.dY.QWordValue = 0) and (Gear^.dY.QWordValue = 0) and (TestCollisionYwithGear(Gear, 1) = 0) then
+ SetLittle(Gear^.dY);
+ Gear^.State := Gear^.State or gstAnimation;
+ if Gear^.Health < cBarrelHealth then Gear^.State:= Gear^.State and not gstFrozen;
+
+ if ((Gear^.dX.QWordValue <> 0)
+ or (Gear^.dY.QWordValue <> 0)) then
+ begin
+ DeleteCI(Gear);
+ AllInactive := false;
+ dxdy:= hwAbs(Gear^.dX)+hwAbs(Gear^.dY);
+ doStepFallingGear(Gear);
+ if (Gear^.State and gstCollision <> 0) and(dxdy > _0_4) then
+ begin
+ if (TestCollisionYwithGear(Gear, 1) <> 0) then
+ begin
+ Gear^.State := Gear^.State or gsttmpFlag;
+ for i:= min(12, hwRound(dxdy*_10)) downto 0 do
+ begin
+ particle := AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12,vgtDust);
+ if particle <> nil then
+ particle^.dX := particle^.dX + (Gear^.dX.QWordValue / 21474836480)
+ end
+ end;
+ inc(Gear^.Damage, hwRound(dxdy * _50))
+ end;
+ CalcRotationDirAngle(Gear);
+ //CheckGearDrowning(Gear)
+ end
+ else
+ begin
+ Gear^.State := Gear^.State or gsttmpFlag;
+ AddCI(Gear)
+ end;
+
+(*
+Attempt to make a barrel knock itself over an edge. Would need more checks to avoid issues like burn damage
+ begin
+ x:= hwRound(Gear^.X);
+ y:= hwRound(Gear^.Y);
+ if (((y+1) and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) then
+ if (Land[y+1, x] = 0) then
+ begin
+ if (((y+1) and LAND_HEIGHT_MASK) = 0) and (((x+Gear^.Radius-2) and LAND_WIDTH_MASK) = 0) and (Land[y+1, x+Gear^.Radius-2] = 0) then
+ Gear^.dX:= -_0_08
+ else if (((y+1 and LAND_HEIGHT_MASK)) = 0) and (((x-(Gear^.Radius-2)) and LAND_WIDTH_MASK) = 0) and (Land[y+1, x-(Gear^.Radius-2)] = 0) then
+ Gear^.dX:= _0_08;
+ end;
+ if Gear^.dX.QWordValue = 0 then AddCI(Gear)
+ end; *)
+
+ if not Gear^.dY.isNegative and (Gear^.dY < _0_001) and (TestCollisionYwithGear(Gear, 1) <> 0) then
+ Gear^.dY := _0;
+ if hwAbs(Gear^.dX) < _0_001 then
+ Gear^.dX := _0;
+
+ if (Gear^.Health > 0) and ((Gear^.Health * 100 div cBarrelHealth) < random(90)) and ((GameTicks and $FF) = 0) then
+ if (cBarrelHealth div Gear^.Health) > 2 then
+ AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmoke)
+ else
+ AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmokeWhite);
+ dec(Gear^.Health, Gear^.Damage);
+ Gear^.Damage := 0;
+ if Gear^.Health <= 0 then
+ doStepCase(Gear);
+end;
+
+procedure doStepCase(Gear: PGear);
+var
+ i, x, y: LongInt;
+ k: TGearType;
+ dX, dY: HWFloat;
+ hog: PHedgehog;
+ sparkles: PVisualGear;
+ gi: PGear;
+begin
+ k := Gear^.Kind;
+
+ if (Gear^.Message and gmDestroy) > 0 then
+ begin
+ DeleteGear(Gear);
+ FreeActionsList;
+ SetAllToActive;
+ // something (hh, mine, etc...) could be on top of the case
+ with CurrentHedgehog^ do
+ if Gear <> nil then
+ Gear^.Message := Gear^.Message and (not (gmLJump or gmHJump));
+ exit
+ end;
+ if (k = gtExplosives) and (Gear^.Health < cBarrelHealth) then Gear^.State:= Gear^.State and not gstFrozen;
+
+ if ((k <> gtExplosives) and (Gear^.Damage > 0)) or ((k = gtExplosives) and (Gear^.Health<=0)) then
+ begin
+ x := hwRound(Gear^.X);
+ y := hwRound(Gear^.Y);
+ hog:= Gear^.Hedgehog;
+
+ DeleteGear(Gear);
+ // <-- delete gear!
+
+ if k = gtCase then
+ begin
+ doMakeExplosion(x, y, 25, hog, EXPLAutoSound);
+ for i:= 0 to 63 do
+ AddGear(x, y, gtFlame, 0, _0, _0, 0);
+ end
+ else if k = gtExplosives then
+ begin
+ doMakeExplosion(x, y, 75, hog, EXPLAutoSound);
+ for i:= 0 to 31 do
+ begin
+ dX := AngleCos(i * 64) * _0_5 * (getrandomf + _1);
+ dY := AngleSin(i * 64) * _0_5 * (getrandomf + _1);
+ AddGear(x, y, gtFlame, 0, dX, dY, 0);
+ AddGear(x, y, gtFlame, gstTmpFlag, -dX, -dY, 0);
+ end
+ end;
+ exit
+ end;
+
+ if k = gtExplosives then
+ begin
+ //if V > _0_03 then Gear^.State:= Gear^.State or gstAnimation;
+ if (hwAbs(Gear^.dX) > _0_15) or ((hwAbs(Gear^.dY) > _0_15) and (hwAbs(Gear^.dX) > _0_02)) then
+ begin
+ Gear^.doStep := @doStepRollingBarrel;
+ exit;
+ end
+ else Gear^.dX:= _0;
+
+ if ((Gear^.Health * 100 div cBarrelHealth) < random(90)) and ((GameTicks and $FF) = 0) then
+ if (cBarrelHealth div Gear^.Health) > 2 then
+ AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmoke)
+ else
+ AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmokeWhite);
+ dec(Gear^.Health, Gear^.Damage);
+ Gear^.Damage := 0;
+ end
+ else
+ begin
+ if (Gear^.Pos <> posCaseHealth) and (GameTicks and $1FFF = 0) then // stir 'em up periodically
+ begin
+ gi := GearsList;
+ while gi <> nil do
+ begin
+ if gi^.Kind = gtGenericFaller then
+ begin
+ gi^.Active:= true;
+ gi^.X:= int2hwFloat(GetRandom(rightX-leftX)+leftX);
+ gi^.Y:= int2hwFloat(GetRandom(LAND_HEIGHT-topY)+topY);
+ gi^.dX:= _90-(GetRandomf*_360);
+ gi^.dY:= _90-(GetRandomf*_360)
+ end;
+ gi := gi^.NextGear
+ end
+ end;
+
+ if Gear^.Timer = 500 then
+ begin
+(* Can't make sparkles team coloured without working out what the next team is going to be. This should be solved, really, since it also screws up
+ voices. Reinforcements voices is heard for active team, not team-to-be. Either that or change crate spawn from end of turn to start, although that
+ has its own complexities. *)
+ // Abuse a couple of gear values to track origin
+ Gear^.Angle:= hwRound(Gear^.Y);
+ Gear^.Tag:= random(2);
+ inc(Gear^.Timer)
+ end;
+ if Gear^.Timer < 1833 then inc(Gear^.Timer);
+ if Gear^.Timer = 1000 then
+ begin
+ sparkles:= AddVisualGear(hwRound(Gear^.X), Gear^.Angle, vgtDust, 1);
+ if sparkles <> nil then
+ begin
+ sparkles^.dX:= 0;
+ sparkles^.dY:= 0;
+ sparkles^.Angle:= 270;
+ if Gear^.Tag = 1 then
+ sparkles^.Tint:= $3744D7FF
+ else sparkles^.Tint:= $FAB22CFF
+ end;
+ end;
+ if Gear^.Timer < 1000 then
+ begin
+ AllInactive:= false;
+ exit
+ end
+ end;
+
+
+ if (Gear^.dY.QWordValue <> 0)
+ or (TestCollisionYwithGear(Gear, 1) = 0) then
+ begin
+ AllInactive := false;
+
+ Gear^.dY := Gear^.dY + cGravity;
+
+ if (Gear^.dY.isNegative) and (TestCollisionYwithGear(Gear, -1) <> 0) then
+ Gear^.dY := _0;
+
+ Gear^.Y := Gear^.Y + Gear^.dY;
+
+ if (not Gear^.dY.isNegative) and (Gear^.dY > _0_001) then
+ SetAllHHToActive(false);
+
+ if (not Gear^.dY.isNegative) and (TestCollisionYwithGear(Gear, 1) <> 0) then
+ begin
+ if (Gear^.dY > _0_2) and (k = gtExplosives) then
+ inc(Gear^.Damage, hwRound(Gear^.dY * _70));
+
+ if Gear^.dY > _0_2 then
+ for i:= min(12, hwRound(Gear^.dY*_10)) downto 0 do
+ AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12, vgtDust);
+
+ Gear^.dY := - Gear^.dY * Gear^.Elasticity;
+ if Gear^.dY > - _0_001 then
+ Gear^.dY := _0
+ else if Gear^.dY < - _0_03 then
+ PlaySound(Gear^.ImpactSound);
+ end;
+ //if Gear^.dY > - _0_001 then Gear^.dY:= _0
+ CheckGearDrowning(Gear);
+ end;
+
+ if (Gear^.dY.QWordValue = 0) then
+ AddCI(Gear)
+ else if (Gear^.dY.QWordValue <> 0) then
+ DeleteCI(Gear)
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+
+procedure doStepTarget(Gear: PGear);
+begin
+ if (Gear^.Timer = 0) and (Gear^.Tag = 0) then
+ PlaySound(sndWarp);
+
+ if (Gear^.Tag = 0) and (Gear^.Timer < 1000) then
+ inc(Gear^.Timer)
+ else if Gear^.Tag = 1 then
+ Gear^.Tag := 2
+ else if Gear^.Tag = 2 then
+ if Gear^.Timer > 0 then
+ dec(Gear^.Timer)
+ else
+ begin
+ DeleteGear(Gear);
+ exit;
+ end;
+
+ doStepCase(Gear)
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepIdle(Gear: PGear);
+begin
+ AllInactive := false;
+ dec(Gear^.Timer);
+ if Gear^.Timer = 0 then
+ begin
+ DeleteGear(Gear);
+ AfterAttack
+ end
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepShover(Gear: PGear);
+var
+ HHGear: PGear;
+begin
+ HHGear := Gear^.Hedgehog^.Gear;
+ HHGear^.State := HHGear^.State or gstNoDamage;
+ DeleteCI(HHGear);
+
+ AmmoShove(Gear, 30, 115);
+
+ HHGear^.State := (HHGear^.State and (not gstNoDamage)) or gstMoving;
+ Gear^.Timer := 250;
+ Gear^.doStep := @doStepIdle
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepWhip(Gear: PGear);
+var
+ HHGear: PGear;
+ i: LongInt;
+begin
+ HHGear := Gear^.Hedgehog^.Gear;
+ HHGear^.State := HHGear^.State or gstNoDamage;
+ DeleteCI(HHGear);
+
+ for i:= 0 to 3 do
+ begin
+ AmmoShove(Gear, 30, 25);
+ Gear^.X := Gear^.X + Gear^.dX * 5
+ end;
+
+ HHGear^.State := (HHGear^.State and (not gstNoDamage)) or gstMoving;
+
+ Gear^.Timer := 250;
+ Gear^.doStep := @doStepIdle
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepFlame(Gear: PGear);
+var
+ gX,gY,i: LongInt;
+ sticky: Boolean;
+ vgt: PVisualGear;
+ tdX,tdY: HWFloat;
+begin
+ sticky:= (Gear^.State and gsttmpFlag) <> 0;
+ if not sticky then AllInactive := false;
+
+ if TestCollisionYwithGear(Gear, 1) = 0 then
+ begin
+ AllInactive := false;
+
+ if ((GameTicks mod 100) = 0) then
+ begin
+ vgt:= AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtFire, gstTmpFlag);
+ if vgt <> nil then
+ begin
+ vgt^.dx:= 0;
+ vgt^.dy:= 0;
+ vgt^.FrameTicks:= 1800 div (Gear^.Tag mod 3 + 2);
+ end;
+ end;
+
+
+ if Gear^.dX.QWordValue > _0_01.QWordValue then
+ Gear^.dX := Gear^.dX * _0_995;
+
+ Gear^.dY := Gear^.dY + cGravity;
+ // if sticky then Gear^.dY := Gear^.dY + cGravity;
+
+ if Gear^.dY.QWordValue > _0_2.QWordValue then
+ Gear^.dY := Gear^.dY * _0_995;
+
+ //if sticky then Gear^.X := Gear^.X + Gear^.dX else
+ Gear^.X := Gear^.X + Gear^.dX + cWindSpeed * 640;
+ Gear^.Y := Gear^.Y + Gear^.dY;
+
+ if (hwRound(Gear^.Y) > cWaterLine) then
+ begin
+ gX := hwRound(Gear^.X);
+ for i:= 0 to 3 do
+ AddVisualGear(gX - 16 + Random(32), cWaterLine - 16 + Random(16), vgtSteam);
+ PlaySound(sndVaporize);
+ DeleteGear(Gear);
+ exit
+ end
+ end
+ else
+ begin
+ if sticky and (GameTicks and $F = 0) then
+ begin
+ Gear^.Radius := 7;
+ tdX:= Gear^.dX;
+ tdY:= Gear^.dY;
+ Gear^.dX.QWordValue:= 120000000;
+ Gear^.dY.QWordValue:= 429496730;
+ Gear^.dX.isNegative:= getrandom(2)<>1;
+ Gear^.dY.isNegative:= true;
+ AmmoShove(Gear, 2, 125);
+ Gear^.dX:= tdX;
+ Gear^.dY:= tdY;
+ Gear^.Radius := 1
+ end;
+ if Gear^.Timer > 0 then
+ begin
+ dec(Gear^.Timer);
+ inc(Gear^.Damage)
+ end
+ else
+ begin
+ gX := hwRound(Gear^.X);
+ gY := hwRound(Gear^.Y);
+ // Standard fire
+ if not sticky then
+ begin
+ if ((GameTicks and $1) = 0) then
+ begin
+ Gear^.Radius := 7;
+ tdX:= Gear^.dX;
+ tdY:= Gear^.dY;
+ Gear^.dX.QWordValue:= 214748365;
+ Gear^.dY.QWordValue:= 429496730;
+ Gear^.dX.isNegative:= getrandom(2)<>1;
+ Gear^.dY.isNegative:= true;
+ AmmoShove(Gear, 6, 100);
+ Gear^.dX:= tdX;
+ Gear^.dY:= tdY;
+ Gear^.Radius := 1;
+ end
+ else if ((GameTicks and $3) = 3) then
+ doMakeExplosion(gX, gY, 8, Gear^.Hedgehog, 0);//, EXPLNoDamage);
+ //DrawExplosion(gX, gY, 4);
+
+ if ((GameTicks and $7) = 0) and (Random(2) = 0) then
+ for i:= Random(2) downto 0 do
+ AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke);
+
+ if Gear^.Health > 0 then
+ dec(Gear^.Health);
+ Gear^.Timer := 450 - Gear^.Tag * 8
+ end
+ else
+ begin
+ // Modified fire
+ if ((GameTicks and $7FF) = 0) and ((GameFlags and gfSolidLand) = 0) then
+ begin
+ DrawExplosion(gX, gY, 4);
+
+ for i:= Random(3) downto 0 do
+ AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke);
+ end;
+
+// This one is interesting. I think I understand the purpose, but I wonder if a bit more fuzzy of kicking could be done with getrandom.
+ Gear^.Timer := 100 - Gear^.Tag * 3;
+ if (Gear^.Damage > 3000+Gear^.Tag*1500) then
+ Gear^.Health := 0
+ end
+ end
+ end;
+ if Gear^.Health = 0 then
+ begin
+ gX := hwRound(Gear^.X);
+ gY := hwRound(Gear^.Y);
+ if not sticky then
+ begin
+ if ((GameTicks and $3) = 0) and (Random(1) = 0) then
+ for i:= Random(2) downto 0 do
+ AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke);
+ end
+ else
+ for i:= Random(3) downto 0 do
+ AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke);
+
+ DeleteGear(Gear)
+ end;
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepFirePunchWork(Gear: PGear);
+var
+ HHGear: PGear;
+begin
+ AllInactive := false;
+ if ((Gear^.Message and gmDestroy) <> 0) then
+ begin
+ DeleteGear(Gear);
+ AfterAttack;
+ exit
+ end;
+
+ HHGear := Gear^.Hedgehog^.Gear;
+ if hwRound(HHGear^.Y) <= Gear^.Tag - 2 then
+ begin
+ Gear^.Tag := hwRound(HHGear^.Y);
+ DrawTunnel(HHGear^.X - int2hwFloat(cHHRadius), HHGear^.Y - _1, _0_5, _0, cHHRadius * 4, 2);
+ HHGear^.State := HHGear^.State or gstNoDamage;
+ Gear^.Y := HHGear^.Y;
+ AmmoShove(Gear, 30, 40);
+ HHGear^.State := HHGear^.State and (not gstNoDamage)
+ end;
+
+ HHGear^.dY := HHGear^.dY + cGravity;
+ if not (HHGear^.dY.isNegative) then
+ begin
+ HHGear^.State := HHGear^.State or gstMoving;
+ DeleteGear(Gear);
+ AfterAttack;
+ exit
+ end;
+
+ if CheckLandValue(hwRound(HHGear^.X), hwRound(HHGear^.Y + HHGear^.dY + SignAs(_6,Gear^.dY)),
+ lfIndestructible) then
+ HHGear^.Y := HHGear^.Y + HHGear^.dY
+end;
+
+procedure doStepFirePunch(Gear: PGear);
+var
+ HHGear: PGear;
+begin
+ AllInactive := false;
+ HHGear := Gear^.Hedgehog^.Gear;
+ DeleteCI(HHGear);
+ //HHGear^.X := int2hwFloat(hwRound(HHGear^.X)) - _0_5; WTF?
+ HHGear^.dX := SignAs(cLittle, Gear^.dX);
+
+ HHGear^.dY := - _0_3;
+
+ Gear^.X := HHGear^.X;
+ Gear^.dX := SignAs(_0_45, Gear^.dX);
+ Gear^.dY := - _0_9;
+ Gear^.doStep := @doStepFirePunchWork;
+ DrawTunnel(HHGear^.X - int2hwFloat(cHHRadius), HHGear^.Y + _1, _0_5, _0, cHHRadius * 4, 5);
+
+ PlaySoundV(TSound(ord(sndFirePunch1) + GetRandom(6)), HHGear^.Hedgehog^.Team^.voicepack)
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+
+procedure doStepParachuteWork(Gear: PGear);
+var
+ HHGear: PGear;
+begin
+ HHGear := Gear^.Hedgehog^.Gear;
+
+ inc(Gear^.Timer);
+
+ if (TestCollisionYwithGear(HHGear, 1) <> 0)
+ or ((HHGear^.State and gstHHDriven) = 0)
+ or CheckGearDrowning(HHGear)
+ or ((Gear^.Message and gmAttack) <> 0) then
+ begin
+ with HHGear^ do
+ begin
+ Message := 0;
+ SetLittle(dX);
+ dY := _0;
+ State := State or gstMoving;
+ end;
+ DeleteGear(Gear);
+ isCursorVisible := false;
+ ApplyAmmoChanges(HHGear^.Hedgehog^);
+ exit
+ end;
+
+ HHGear^.X := HHGear^.X + cWindSpeed * 200;
+
+ if (Gear^.Message and gmLeft) <> 0 then
+ HHGear^.X := HHGear^.X - cMaxWindSpeed * 80
+
+ else if (Gear^.Message and gmRight) <> 0 then
+ HHGear^.X := HHGear^.X + cMaxWindSpeed * 80;
+
+ if (Gear^.Message and gmUp) <> 0 then
+ HHGear^.Y := HHGear^.Y - cGravity * 40
+
+ else if (Gear^.Message and gmDown) <> 0 then
+ HHGear^.Y := HHGear^.Y + cGravity * 40;
+
+ // don't drift into obstacles
+ if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then
+ HHGear^.X := HHGear^.X - int2hwFloat(hwSign(HHGear^.dX));
+ HHGear^.Y := HHGear^.Y + cGravity * 100;
+ Gear^.X := HHGear^.X;
+ Gear^.Y := HHGear^.Y
+end;
+
+procedure doStepParachute(Gear: PGear);
+var
+ HHGear: PGear;
+begin
+ HHGear := Gear^.Hedgehog^.Gear;
+
+ DeleteCI(HHGear);
+
+ AfterAttack;
+
+ HHGear^.State := HHGear^.State and (not (gstAttacking or gstAttacked or gstMoving));
+ HHGear^.Message := HHGear^.Message and (not gmAttack);
+
+ Gear^.doStep := @doStepParachuteWork;
+
+ Gear^.Message := HHGear^.Message;
+ doStepParachuteWork(Gear)
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepAirAttackWork(Gear: PGear);
+begin
+ AllInactive := false;
+ Gear^.X := Gear^.X + cAirPlaneSpeed * Gear^.Tag;
+
+ if (Gear^.Health > 0)and(not (Gear^.X < Gear^.dX))and(Gear^.X < Gear^.dX + cAirPlaneSpeed) then
+ begin
+ dec(Gear^.Health);
+ case Gear^.State of
+ 0: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtAirBomb, 0, cBombsSpeed * Gear^.Tag, _0, 0);
+ 1: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtMine, 0, cBombsSpeed * Gear^.Tag, _0, 0);
+ 2: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtNapalmBomb, 0, cBombsSpeed * Gear^.Tag, _0, 0);
+ 3: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtDrill, gsttmpFlag, cBombsSpeed * Gear^.Tag, _0, Gear^.Timer + 1);
+ //4: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtWaterMelon, 0, cBombsSpeed *
+ // Gear^.Tag, _0, 5000);
+ end;
+ Gear^.dX := Gear^.dX + int2hwFloat(30 * Gear^.Tag);
+ StopSoundChan(Gear^.SoundChannel, 4000);
+ end;
+
+ if (GameTicks and $3F) = 0 then
+ AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace);
+
+ if (hwRound(Gear^.X) > (max(LAND_WIDTH,4096)+2048)) or (hwRound(Gear^.X) < -2048) then
+ begin
+ // avoid to play forever (is this necessary?)
+ StopSoundChan(Gear^.SoundChannel);
+ DeleteGear(Gear)
+ end;
+end;
+
+procedure doStepAirAttack(Gear: PGear);
+begin
+ AllInactive := false;
+
+ if Gear^.X.QWordValue = 0 then
+ begin
+ Gear^.Tag := 1;
+ Gear^.X := -_2048;
+ end
+ else
+ begin
+ Gear^.Tag := -1;
+ Gear^.X := int2hwFloat(max(LAND_WIDTH,4096) + 2048);
+ end;
+
+ Gear^.Y := int2hwFloat(topY-300);
+ Gear^.dX := int2hwFloat(Gear^.Target.X - 5 * Gear^.Tag * 15);
+
+ // calcs for Napalm Strike, so that it will hit the target (without wind at least :P)
+ if (Gear^.State = 2) then
+ Gear^.dX := Gear^.dX - cBombsSpeed * Gear^.Tag * 900
+ // calcs for regular falling gears
+ else if (int2hwFloat(Gear^.Target.Y) - Gear^.Y > _0) then
+ Gear^.dX := Gear^.dX - cBombsSpeed * hwSqrt((int2hwFloat(Gear^.Target.Y) - Gear^.Y) * 2 /
+ cGravity) * Gear^.Tag;
+
+ Gear^.Health := 6;
+ Gear^.doStep := @doStepAirAttackWork;
+ Gear^.SoundChannel := LoopSound(sndPlane, 4000);
+
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+
+procedure doStepAirBomb(Gear: PGear);
+begin
+ AllInactive := false;
+ doStepFallingGear(Gear);
+ if (Gear^.State and gstCollision) <> 0 then
+ begin
+ doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, Gear^.Hedgehog, EXPLAutoSound);
+ DeleteGear(Gear);
+ with mobileRecord do
+ if (performRumble <> nil) and (not fastUntilLag) then
+ performRumble(kSystemSoundID_Vibrate);
+ exit
+ end;
+ if (GameTicks and $3F) = 0 then
+ AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace)
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+
+procedure doStepGirder(Gear: PGear);
+var
+ HHGear: PGear;
+ x, y, tx, ty: hwFloat;
+begin
+ AllInactive := false;
+
+ HHGear := Gear^.Hedgehog^.Gear;
+ tx := int2hwFloat(Gear^.Target.X);
+ ty := int2hwFloat(Gear^.Target.Y);
+ x := HHGear^.X;
+ y := HHGear^.Y;
+
+ if (Distance(tx - x, ty - y) > _256)
+ or (not TryPlaceOnLand(Gear^.Target.X - SpritesData[sprAmGirder].Width div 2, Gear^.Target.Y - SpritesData[sprAmGirder].Height div 2, sprAmGirder, Gear^.State, true, false)) then
+ begin
+ PlaySound(sndDenied);
+ HHGear^.Message := HHGear^.Message and (not gmAttack);
+ HHGear^.State := HHGear^.State and (not gstAttacking);
+ HHGear^.State := HHGear^.State or gstHHChooseTarget;
+ isCursorVisible := true;
+ DeleteGear(Gear)
+ end
+ else
+ begin
+ PlaySound(sndPlaced);
+ DeleteGear(Gear);
+ AfterAttack;
+ end;
+
+ HHGear^.State := HHGear^.State and (not (gstAttacking or gstAttacked));
+ HHGear^.Message := HHGear^.Message and (not gmAttack);
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepTeleportAfter(Gear: PGear);
+var
+ HHGear: PGear;
+begin
+ HHGear := Gear^.Hedgehog^.Gear;
+ doStepHedgehogMoving(HHGear);
+ // if not infattack mode wait for hedgehog finish falling to collect cases
+ if ((GameFlags and gfInfAttack) <> 0)
+ or ((HHGear^.State and gstMoving) = 0)
+ or (Gear^.Hedgehog^.Gear^.Damage > 0)
+ or ((HHGear^.State and gstDrowning) = 1) then
+ begin
+ DeleteGear(Gear);
+ AfterAttack
+ end
+end;
+
+procedure doStepTeleportAnim(Gear: PGear);
+begin
+ if (Gear^.Hedgehog^.Gear^.Damage > 0) then
+ begin
+ DeleteGear(Gear);
+ AfterAttack;
+ end;
+ inc(Gear^.Timer);
+ if Gear^.Timer = 65 then
+ begin
+ Gear^.Timer := 0;
+ inc(Gear^.Pos);
+ if Gear^.Pos = 11 then
+ Gear^.doStep := @doStepTeleportAfter
+ end;
+end;
+
+procedure doStepTeleport(Gear: PGear);
+var
+ HHGear: PGear;
+begin
+ AllInactive := false;
+
+ HHGear := Gear^.Hedgehog^.Gear;
+ if not TryPlaceOnLand(Gear^.Target.X - SpritesData[sprHHTelepMask].Width div 2,
+ Gear^.Target.Y - SpritesData[sprHHTelepMask].Height div 2,
+ sprHHTelepMask, 0, false, false) then
+ begin
+ HHGear^.Message := HHGear^.Message and (not gmAttack);
+ HHGear^.State := HHGear^.State and (not gstAttacking);
+ HHGear^.State := HHGear^.State or gstHHChooseTarget;
+ DeleteGear(Gear);
+ isCursorVisible := true;
+ PlaySound(sndDenied)
+ end
+ else
+ begin
+ DeleteCI(HHGear);
+ SetAllHHToActive;
+ Gear^.doStep := @doStepTeleportAnim;
+
+ // copy old HH position and direction to Gear (because we need them for drawing the vanishing hog)
+ Gear^.dX := HHGear^.dX;
+ // retrieve the cursor direction (it was previously copied to X so it doesn't get lost)
+ HHGear^.dX.isNegative := (Gear^.X.QWordValue <> 0);
+ Gear^.X := HHGear^.X;
+ Gear^.Y := HHGear^.Y;
+ HHGear^.X := int2hwFloat(Gear^.Target.X);
+ HHGear^.Y := int2hwFloat(Gear^.Target.Y);
+ HHGear^.State := HHGear^.State or gstMoving;
+ Gear^.Hedgehog^.Unplaced := false;
+ isCursorVisible := false;
+ playSound(sndWarp)
+ end;
+ Gear^.Target.X:= NoPointX
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepSwitcherWork(Gear: PGear);
+var
+ HHGear: PGear;
+ hedgehog: PHedgehog;
+ State: Longword;
+begin
+ AllInactive := false;
+
+ if ((Gear^.Message and (not gmSwitch)) <> 0) or (TurnTimeLeft = 0) then
+ begin
+ hedgehog := Gear^.Hedgehog;
+ //Msg := Gear^.Message and (not gmSwitch);
+ DeleteGear(Gear);
+ ApplyAmmoChanges(hedgehog^);
+
+ HHGear := CurrentHedgehog^.Gear;
+ ApplyAmmoChanges(HHGear^.Hedgehog^);
+ //HHGear^.Message := Msg;
+ exit
+ end;
+
+ if (Gear^.Message and gmSwitch) <> 0 then
+ begin
+ HHGear := CurrentHedgehog^.Gear;
+ HHGear^.Message := HHGear^.Message and (not gmSwitch);
+ Gear^.Message := Gear^.Message and (not gmSwitch);
+ State := HHGear^.State;
+ HHGear^.State := 0;
+ HHGear^.Z := cHHZ;
+ HHGear^.Active := false;
+ HHGear^.Message:= HHGear^.Message or gmRemoveFromList or gmAddToList;
+
+ PlaySound(sndSwitchHog);
+
+ repeat
+ CurrentTeam^.CurrHedgehog := Succ(CurrentTeam^.CurrHedgehog) mod (CurrentTeam^.HedgehogsNumber);
+ until (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil) and
+ (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear^.Damage = 0) and
+ (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Effects[heFrozen]=0);
+
+ SwitchCurrentHedgehog(@CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog]);
+ AmmoMenuInvalidated:= true;
+
+ HHGear := CurrentHedgehog^.Gear;
+ HHGear^.State := State;
+ HHGear^.Active := true;
+ FollowGear := HHGear;
+ HHGear^.Z := cCurrHHZ;
+ HHGear^.Message:= HHGear^.Message or gmRemoveFromList or gmAddToList;
+ Gear^.X := HHGear^.X;
+ Gear^.Y := HHGear^.Y
+ end;
+end;
+
+procedure doStepSwitcher(Gear: PGear);
+var
+ HHGear: PGear;
+begin
+ Gear^.doStep := @doStepSwitcherWork;
+
+ HHGear := Gear^.Hedgehog^.Gear;
+ OnUsedAmmo(HHGear^.Hedgehog^);
+ with HHGear^ do
+ begin
+ State := State and (not gstAttacking);
+ Message := Message and (not gmAttack)
+ end
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepMortar(Gear: PGear);
+var
+ dX, dY, gdX, gdY: hwFloat;
+ i: LongInt;
+begin
+ AllInactive := false;
+ gdX := Gear^.dX;
+ gdY := Gear^.dY;
+
+ doStepFallingGear(Gear);
+ if (Gear^.State and gstCollision) <> 0 then
+ begin
+ doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 20, Gear^.Hedgehog, EXPLAutoSound);
+ gdX.isNegative := not gdX.isNegative;
+ gdY.isNegative := not gdY.isNegative;
+ gdX:= gdX*_0_2;
+ gdY:= gdY*_0_2;
+
+ for i:= 0 to 4 do
+ begin
+ dX := gdX + rndSign(GetRandomf) * _0_03;
+ dY := gdY + rndSign(GetRandomf) * _0_03;
+ AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtCluster, 0, dX, dY, 25);
+ end;
+
+ DeleteGear(Gear);
+ exit
+ end;
+
+ if (GameTicks and $3F) = 0 then
+ begin
+ if hwRound(Gear^.Y) > cWaterLine then
+ AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtBubble)
+ else AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace)
+ end
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepKamikazeWork(Gear: PGear);
+var
+ i: LongWord;
+ HHGear: PGear;
+ sparkles: PVisualGear;
+ hasWishes: boolean;
+begin
+ AllInactive := false;
+ hasWishes:= ((Gear^.Message and (gmPrecise or gmSwitch)) = (gmPrecise or gmSwitch));
+ if hasWishes then
+ Gear^.AdvBounce:= 1;
+
+ HHGear := Gear^.Hedgehog^.Gear;
+ if HHGear = nil then
+ begin
+ DeleteGear(Gear);
+ exit
+ end;
+
+ HHGear^.State := HHGear^.State or gstNoDamage;
+ DeleteCI(HHGear);
+
+ Gear^.X := HHGear^.X;
+ Gear^.Y := HHGear^.Y;
+ if (GameTicks mod 2 = 0) and hasWishes then
+ begin
+ sparkles:= AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtDust, 1);
+ if sparkles <> nil then
+ begin
+ sparkles^.Tint:= ((random(210)+45) shl 24) or ((random(210)+45) shl 16) or ((random(210)+45) shl 8) or $FF;
+ sparkles^.Angle:= random(360);
+ end
+ end;
+
+ i := 2;
+ repeat
+
+ Gear^.X := Gear^.X + HHGear^.dX;
+ Gear^.Y := Gear^.Y + HHGear^.dY;
+ HHGear^.X := Gear^.X;
+ HHGear^.Y := Gear^.Y;
+
+ inc(Gear^.Damage, 2);
+
+ // if TestCollisionXwithGear(HHGear, hwSign(Gear^.dX))
+ // or TestCollisionYwithGear(HHGear, hwSign(Gear^.dY)) then inc(Gear^.Damage, 3);
+
+ dec(i)
+ until (i = 0)
+ or (Gear^.Damage > Gear^.Health);
+
+ inc(upd);
+ if upd > 3 then
+ begin
+ if Gear^.Health < 1500 then
+ begin
+ if Gear^.AdvBounce <> 0 then
+ Gear^.Pos := 3
+ else
+ Gear^.Pos := 2;
+ end;
+
+ AmmoShove(Gear, 30, 40);
+
+ DrawTunnel(HHGear^.X - HHGear^.dX * 10,
+ HHGear^.Y - _2 - HHGear^.dY * 10 + hwAbs(HHGear^.dY) * 2,
+ HHGear^.dX,
+ HHGear^.dY,
+ 20 + cHHRadius * 2,
+ cHHRadius * 2 + 7);
+
+ upd := 0
+ end;
+
+ if Gear^.Health < Gear^.Damage then
+ begin
+ doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, Gear^.Hedgehog, EXPLAutoSound);
+ if hasWishes then
+ for i:= 0 to 31 do
+ begin
+ sparkles:= AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtStraightShot);
+ if sparkles <> nil then
+ with sparkles^ do
+ begin
+ Tint:= ((random(210)+45) shl 24) or ((random(210)+45) shl 16) or ((random(210)+45) shl 8) or $FF;
+ Angle:= random(360);
+ dx:= 0.001 * (random(200));
+ dy:= 0.001 * (random(200));
+ if random(2) = 0 then
+ dx := -dx;
+ if random(2) = 0 then
+ dy := -dy;
+ FrameTicks:= random(400) + 250
+ end
+ end;
+ AfterAttack;
+ HHGear^.Message:= HHGear^.Message or gmDestroy;
+ DeleteGear(Gear);
+ end
+ else
+ begin
+ dec(Gear^.Health, Gear^.Damage);
+ Gear^.Damage := 0
+ end
+end;
+
+procedure doStepKamikazeIdle(Gear: PGear);
+begin
+ AllInactive := false;
+ dec(Gear^.Timer);
+ if Gear^.Timer = 0 then
+ begin
+ Gear^.Pos := 1;
+ PlaySoundV(sndKamikaze, Gear^.Hedgehog^.Team^.voicepack);
+ Gear^.doStep := @doStepKamikazeWork
+ end
+end;
+
+procedure doStepKamikaze(Gear: PGear);
+var
+ HHGear: PGear;
+begin
+ AllInactive := false;
+
+ HHGear := Gear^.Hedgehog^.Gear;
+
+ HHGear^.dX := Gear^.dX;
+ HHGear^.dY := Gear^.dY;
+
+ Gear^.dX := SignAs(_0_45, Gear^.dX);
+ Gear^.dY := - _0_9;
+
+ Gear^.Timer := 550;
+
+ Gear^.doStep := @doStepKamikazeIdle
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+
+const cakeh = 27;
+var
+ CakePoints: array[0..Pred(cakeh)] of record
+ x, y: hwFloat;
+ end;
+ CakeI: Longword;
+
+procedure doStepCakeExpl(Gear: PGear);
+begin
+ AllInactive := false;
+
+ inc(Gear^.Tag);
+ if Gear^.Tag < 2250 then
+ exit;
+
+ doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), cakeDmg, Gear^.Hedgehog, EXPLAutoSound);
+ AfterAttack;
+ DeleteGear(Gear)
+end;
+
+procedure doStepCakeDown(Gear: PGear);
+var
+ gi: PGear;
+ dmg, dmgBase: LongInt;
+ fX, fY, tdX, tdY: hwFloat;
+begin
+ AllInactive := false;
+
+ inc(Gear^.Tag);
+ if Gear^.Tag < 100 then
+ exit;
+ Gear^.Tag := 0;
+
+ if Gear^.Pos = 0 then
+ begin
+///////////// adapted from doMakeExplosion ///////////////////////////
+ //fX:= Gear^.X;
+ //fY:= Gear^.Y;
+ //fX.QWordValue:= fX.QWordValue and $FFFFFFFF00000000;
+ //fY.QWordValue:= fY.QWordValue and $FFFFFFFF00000000;
+ fX:= int2hwFloat(hwRound(Gear^.X));
+ fY:= int2hwFloat(hwRound(Gear^.Y));
+ dmgBase:= cakeDmg shl 1 + cHHRadius div 2;
+ gi := GearsList;
+ while gi <> nil do
+ begin
+ if gi^.Kind = gtHedgehog then
+ begin
+ dmg:= 0;
+ tdX:= gi^.X-fX;
+ tdY:= gi^.Y-fY;
+ if hwRound(hwAbs(tdX)+hwAbs(tdY)) < dmgBase then
+ dmg:= dmgBase - max(hwRound(Distance(tdX, tdY)),gi^.Radius);
+ if (dmg > 1) then dmg:= ModifyDamage(min(dmg div 2, cakeDmg), gi);
+ if (dmg > 1) then
+ if (CurrentHedgehog^.Gear = gi) and (not gi^.Invulnerable) then
+ gi^.State := gi^.State or gstLoser
+ else
+ gi^.State := gi^.State or gstWinner;
+ end;
+ gi := gi^.NextGear
+ end;
+//////////////////////////////////////////////////////////////////////
+ Gear^.doStep := @doStepCakeExpl;
+ PlaySound(sndCake)
+ end
+ else dec(Gear^.Pos)
+end;
+
+
+procedure doStepCakeWork(Gear: PGear);
+var
+ tdx, tdy: hwFloat;
+begin
+ AllInactive := false;
+
+ inc(Gear^.Tag);
+ if Gear^.Tag < 7 then
+ exit;
+
+ dec(Gear^.Health);
+ Gear^.Timer := Gear^.Health*10;
+ if Gear^.Health mod 100 = 0 then
+ Gear^.PortalCounter:= 0;
+ // This is not seconds, but at least it is *some* feedback
+ if (Gear^.Health = 0) or ((Gear^.Message and gmAttack) <> 0) then
+ begin
+ FollowGear := Gear;
+ Gear^.RenderTimer := false;
+ Gear^.doStep := @doStepCakeDown;
+ exit
+ end;
+
+ cakeStep(Gear);
+
+ if Gear^.Tag = 0 then
+ begin
+ CakeI := (CakeI + 1) mod cakeh;
+ tdx := CakePoints[CakeI].x - Gear^.X;
+ tdy := - CakePoints[CakeI].y + Gear^.Y;
+ CakePoints[CakeI].x := Gear^.X;
+ CakePoints[CakeI].y := Gear^.Y;
+ Gear^.DirAngle := DxDy2Angle(tdx, tdy);
+ end;
+end;
+
+procedure doStepCakeUp(Gear: PGear);
+var
+ i: Longword;
+begin
+ AllInactive := false;
+
+ inc(Gear^.Tag);
+ if Gear^.Tag < 100 then
+ exit;
+ Gear^.Tag := 0;
+
+ if Gear^.Pos = 6 then
+ begin
+ for i:= 0 to Pred(cakeh) do
+ begin
+ CakePoints[i].x := Gear^.X;
+ CakePoints[i].y := Gear^.Y
+ end;
+ CakeI := 0;
+ Gear^.doStep := @doStepCakeWork
+ end
+ else
+ inc(Gear^.Pos)
+end;
+
+procedure doStepCakeFall(Gear: PGear);
+begin
+ AllInactive := false;
+
+ Gear^.dY := Gear^.dY + cGravity;
+ if TestCollisionYwithGear(Gear, 1) <> 0 then
+ Gear^.doStep := @doStepCakeUp
+ else
+ begin
+ Gear^.Y := Gear^.Y + Gear^.dY;
+ if CheckGearDrowning(Gear) then
+ AfterAttack
+ end
+end;
+
+procedure doStepCake(Gear: PGear);
+var
+ HHGear: PGear;
+begin
+ AllInactive := false;
+
+ HHGear := Gear^.Hedgehog^.Gear;
+ HHGear^.Message := HHGear^.Message and (not gmAttack);
+ Gear^.CollisionMask:= lfNotCurrentMask;
+
+ FollowGear := Gear;
+
+ Gear^.doStep := @doStepCakeFall
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepSeductionWork(Gear: PGear);
+var i: LongInt;
+ hogs: PGearArrayS;
+begin
+ AllInactive := false;
+ hogs := GearsNear(Gear^.X, Gear^.Y, gtHedgehog, Gear^.Radius);
+ if hogs.size > 0 then
+ begin
+ for i:= 0 to hogs.size - 1 do
+ with hogs.ar^[i]^ do
+ begin
+ if hogs.ar^[i] <> CurrentHedgehog^.Gear then
+ begin
+ dX:= _50 * cGravity * (Gear^.X - X) / _25;
+ dY:= -_450 * cGravity;
+ Active:= true;
+ end
+ end;
+ end ;
+ AfterAttack;
+ DeleteGear(Gear);
+(*
+ Gear^.X := Gear^.X + Gear^.dX;
+ Gear^.Y := Gear^.Y + Gear^.dY;
+ x := hwRound(Gear^.X);
+ y := hwRound(Gear^.Y);
+
+ if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) then
+ if (Land[y, x] <> 0) then
+ begin
+ Gear^.dX.isNegative := not Gear^.dX.isNegative;
+ Gear^.dY.isNegative := not Gear^.dY.isNegative;
+ Gear^.dX := Gear^.dX * _1_5;
+ Gear^.dY := Gear^.dY * _1_5 - _0_3;
+ AmmoShove(Gear, 0, 40);
+ AfterAttack;
+ DeleteGear(Gear)
+ end
+ else
+ else
+ begin
+ AfterAttack;
+ DeleteGear(Gear)
+ end*)
+end;
+
+procedure doStepSeductionWear(Gear: PGear);
+var heart: PVisualGear;
+begin
+ AllInactive := false;
+ inc(Gear^.Timer);
+ if Gear^.Timer > 250 then
+ begin
+ Gear^.Timer := 0;
+ inc(Gear^.Pos);
+ if Gear^.Pos = 5 then
+ PlaySoundV(sndYoohoo, Gear^.Hedgehog^.Team^.voicepack)
+ end;
+
+ if (Gear^.Pos = 14) and (RealTicks and $3 = 0) then
+ begin
+ heart:= AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtStraightShot);
+ if heart <> nil then
+ with heart^ do
+ begin
+ dx:= 0.001 * (random(200));
+ dy:= 0.001 * (random(200));
+ if random(2) = 0 then
+ dx := -dx;
+ if random(2) = 0 then
+ dy := -dy;
+ FrameTicks:= random(750) + 1000;
+ State:= ord(sprSeduction)
+ end;
+ end;
+
+ if Gear^.Pos = 15 then
+ Gear^.doStep := @doStepSeductionWork
+end;
+
+procedure doStepSeduction(Gear: PGear);
+begin
+ AllInactive := false;
+ //DeleteCI(Gear^.Hedgehog^.Gear);
+ Gear^.doStep := @doStepSeductionWear
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepWaterUp(Gear: PGear);
+var
+ i: LongWord;
+begin
+ if (Gear^.Tag = 0)
+ or (cWaterLine = 0) then
+ begin
+ DeleteGear(Gear);
+ exit
+ end;
+
+ AllInactive := false;
+
+ inc(Gear^.Timer);
+ if Gear^.Timer = 17 then
+ Gear^.Timer := 0
+ else
+ exit;
+
+ if cWaterLine > 0 then
+ begin
+ dec(cWaterLine);
+ for i:= 0 to LAND_WIDTH - 1 do
+ Land[cWaterLine, i] := 0;
+ SetAllToActive
+ end;
+
+ dec(Gear^.Tag);
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepDrillDrilling(Gear: PGear);
+var
+ t: PGearArray;
+ tempColl: Word;
+begin
+ AllInactive := false;
+ if (Gear^.Timer > 0) and (Gear^.Timer mod 10 <> 0) then
+ begin
+ dec(Gear^.Timer);
+ exit;
+ end;
+
+ DrawTunnel(Gear^.X, Gear^.Y, Gear^.dX, Gear^.dY, 2, 6);
+ Gear^.X := Gear^.X + Gear^.dX;
+ Gear^.Y := Gear^.Y + Gear^.dY;
+ if (Gear^.Timer mod 30) = 0 then
+ AddVisualGear(hwRound(Gear^.X + _20 * Gear^.dX), hwRound(Gear^.Y + _20 * Gear^.dY), vgtDust);
+ if (CheckGearDrowning(Gear)) then
+ begin
+ StopSoundChan(Gear^.SoundChannel);
+ exit
+ end;
+
+ tempColl:= Gear^.CollisionMask;
+ Gear^.CollisionMask:= $007F;
+ if (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) <> 0) or TestCollisionXWithGear(Gear, hwSign(Gear^.dX)) or (GameTicks > Gear^.FlightTime) then
+ t := CheckGearsCollision(Gear)
+ else t := nil;
+ Gear^.CollisionMask:= tempColl;
+ //fixes drill not exploding when touching HH bug
+
+ if (Gear^.Timer = 0) or ((t <> nil) and (t^.Count <> 0))
+ or ( ((Gear^.State and gsttmpFlag) = 0) and (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) = 0) and (not TestCollisionXWithGear(Gear, hwSign(Gear^.dX))))
+// CheckLandValue returns true if the type isn't matched
+ or (not CheckLandValue(hwRound(Gear^.X), hwRound(Gear^.Y), lfIndestructible)) then
+ begin
+ //out of time or exited ground
+ StopSoundChan(Gear^.SoundChannel);
+ if (Gear^.State and gsttmpFlag) <> 0 then
+ doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, Gear^.Hedgehog, EXPLAutoSound)
+ else
+ doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound);
+ DeleteGear(Gear);
+ exit
+ end
+
+ else if (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) = 0) and (not TestCollisionXWithGear(Gear, hwSign(Gear^.dX))) then
+ begin
+ StopSoundChan(Gear^.SoundChannel);
+ Gear^.Tag := 1;
+ Gear^.doStep := @doStepDrill
+ end;
+
+ dec(Gear^.Timer);
+end;
+
+procedure doStepDrill(Gear: PGear);
+var
+ t: PGearArray;
+ oldDx, oldDy: hwFloat;
+ t2: hwFloat;
+begin
+ AllInactive := false;
+
+ if (Gear^.State and gsttmpFlag) = 0 then
+ Gear^.dX := Gear^.dX + cWindSpeed;
+
+ oldDx := Gear^.dX;
+ oldDy := Gear^.dY;
+
+ doStepFallingGear(Gear);
+
+ if (GameTicks and $3F) = 0 then
+ begin
+ if hwRound(Gear^.Y) > cWaterLine then
+ AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtBubble)
+ else AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace)
+ end;
+
+ if ((Gear^.State and gstCollision) <> 0) then
+ begin
+ //hit
+ Gear^.dX := oldDx;
+ Gear^.dY := oldDy;
+
+ if GameTicks > Gear^.FlightTime then
+ t := CheckGearsCollision(Gear)
+ else
+ t := nil;
+ if (t = nil) or (t^.Count = 0) then
+ begin
+ //hit the ground not the HH
+ t2 := _0_5 / Distance(Gear^.dX, Gear^.dY);
+ Gear^.dX := Gear^.dX * t2;
+ Gear^.dY := Gear^.dY * t2;
+ end
+
+ else if (t <> nil) then
+ begin
+ //explode right on contact with HH
+ if (Gear^.State and gsttmpFlag) <> 0 then
+ doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, Gear^.Hedgehog, EXPLAutoSound)
+ else
+ doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound);
+ DeleteGear(Gear);
+ exit;
+ end;
+
+ Gear^.SoundChannel := LoopSound(sndDrillRocket);
+ Gear^.doStep := @doStepDrillDrilling;
+
+ if (Gear^.State and gsttmpFlag) <> 0 then
+ gear^.RenderTimer:= true;
+ if Gear^.Timer > 0 then dec(Gear^.Timer)
+ end
+ else if ((Gear^.State and gsttmpFlag) <> 0) and (Gear^.Tag <> 0) then
+ begin
+ if Gear^.Timer > 0 then
+ dec(Gear^.Timer)
+ else
+ begin
+ doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, Gear^.Hedgehog, EXPLAutoSound);
+ DeleteGear(Gear);
+ end
+ end;
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepBallgunWork(Gear: PGear);
+var
+ HHGear, ball: PGear;
+ rx, ry: hwFloat;
+ gX, gY: LongInt;
+begin
+ AllInactive := false;
+ dec(Gear^.Timer);
+ HHGear := Gear^.Hedgehog^.Gear;
+ HedgehogChAngle(HHGear);
+ gX := hwRound(Gear^.X) + GetLaunchX(amBallgun, hwSign(HHGear^.dX), HHGear^.Angle);
+ gY := hwRound(Gear^.Y) + GetLaunchY(amBallgun, HHGear^.Angle);
+ if (Gear^.Timer mod 100) = 0 then
+ begin
+ rx := rndSign(getRandomf * _0_1);
+ ry := rndSign(getRandomf * _0_1);
+
+ ball:= AddGear(gx, gy, gtBall, 0, SignAs(AngleSin(HHGear^.Angle) * _0_8, HHGear^.dX) + rx, AngleCos(HHGear^.Angle) * ( - _0_8) + ry, 0);
+ ball^.CollisionMask:= lfNotCurrentMask;
+
+ PlaySound(sndGun);
+ end;
+
+ if (Gear^.Timer = 0) or ((HHGear^.State and gstHHDriven) = 0) then
+ begin
+ DeleteGear(Gear);
+ AfterAttack
+ end
+end;
+
+procedure doStepBallgun(Gear: PGear);
+var
+ HHGear: PGear;
+begin
+ HHGear := Gear^.Hedgehog^.Gear;
+ HHGear^.Message := HHGear^.Message and (not (gmUp or gmDown));
+ HHGear^.State := HHGear^.State or gstNotKickable;
+ Gear^.doStep := @doStepBallgunWork
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepRCPlaneWork(Gear: PGear);
+
+const cAngleSpeed = 3;
+var
+ HHGear: PGear;
+ i: LongInt;
+ dX, dY: hwFloat;
+ fChanged: boolean;
+ trueAngle: Longword;
+ t: PGear;
+begin
+ AllInactive := false;
+
+ HHGear := Gear^.Hedgehog^.Gear;
+ FollowGear := Gear;
+
+ if Gear^.Timer > 0 then
+ dec(Gear^.Timer);
+
+ fChanged := false;
+ if ((HHGear^.State and gstHHDriven) = 0) or (Gear^.Timer = 0) then
+ begin
+ fChanged := true;
+ if Gear^.Angle > 2048 then
+ dec(Gear^.Angle)
+ else if Gear^.Angle < 2048 then
+ inc(Gear^.Angle)
+ else fChanged := false
+ end
+ else
+ begin
+ if ((Gear^.Message and gmLeft) <> 0) then
+ begin
+ fChanged := true;
+ Gear^.Angle := (Gear^.Angle + (4096 - cAngleSpeed)) mod 4096
+ end;
+
+ if ((Gear^.Message and gmRight) <> 0) then
+ begin
+ fChanged := true;
+ Gear^.Angle := (Gear^.Angle + cAngleSpeed) mod 4096
+ end
+ end;
+
+ if fChanged then
+ begin
+ Gear^.dX.isNegative := (Gear^.Angle > 2048);
+ if Gear^.dX.isNegative then
+ trueAngle := 4096 - Gear^.Angle
+ else
+ trueAngle := Gear^.Angle;
+
+ Gear^.dX := SignAs(AngleSin(trueAngle), Gear^.dX) * _0_25;
+ Gear^.dY := AngleCos(trueAngle) * -_0_25;
+ end;
+
+ Gear^.X := Gear^.X + Gear^.dX;
+ Gear^.Y := Gear^.Y + Gear^.dY;
+
+ if (GameTicks and $FF) = 0 then
+ if Gear^.Timer < 3500 then
+ AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtEvilTrace)
+ else
+ AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace);
+
+ if ((HHGear^.Message and gmAttack) <> 0) and (Gear^.Health <> 0) then
+ begin
+ HHGear^.Message := HHGear^.Message and (not gmAttack);
+ AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtAirBomb, 0, Gear^.dX * _0_5, Gear^.dY *
+ _0_5, 0);
+ dec(Gear^.Health)
+ end;
+
+ if ((HHGear^.Message and gmLJump) <> 0) and ((Gear^.State and gsttmpFlag) = 0) then
+ begin
+ Gear^.State := Gear^.State or gsttmpFlag;
+ PauseMusic;
+ playSound(sndRideOfTheValkyries);
+ end;
+
+ // pickup bonuses
+ t := CheckGearNear(Gear, gtCase, 36, 36);
+ if t <> nil then
+ PickUp(HHGear, t);
+
+ CheckCollision(Gear);
+
+ if ((Gear^.State and gstCollision) <> 0) or CheckGearDrowning(Gear) then
+ begin
+ StopSoundChan(Gear^.SoundChannel);
+ StopSound(sndRideOfTheValkyries);
+ ResumeMusic;
+
+ if ((Gear^.State and gstCollision) <> 0) then
+ begin
+ doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 25, Gear^.Hedgehog, EXPLAutoSound);
+ for i:= 0 to 15 do
+ begin
+ dX := AngleCos(i * 64) * _0_5 * (GetRandomf + _1);
+ dY := AngleSin(i * 64) * _0_5 * (GetRandomf + _1);
+ AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtFlame, 0, dX, dY, 0);
+ AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtFlame, 0, dX, -dY, 0);
+ end;
+ DeleteGear(Gear)
+ end;
+
+ AfterAttack;
+ CurAmmoGear := nil;
+ if (GameFlags and gfInfAttack) = 0 then
+ begin
+ if TagTurnTimeLeft = 0 then
+ TagTurnTimeLeft:= TurnTimeLeft;
+
+ TurnTimeLeft:= 14 * 125;
+ end;
+
+ HHGear^.Message := 0;
+ ParseCommand('/taunt ' + #1, true)
+ end
+end;
+
+procedure doStepRCPlane(Gear: PGear);
+var
+ HHGear: PGear;
+begin
+ HHGear := Gear^.Hedgehog^.Gear;
+ HHGear^.Message := 0;
+ HHGear^.State := HHGear^.State or gstNotKickable;
+ Gear^.Angle := HHGear^.Angle;
+ Gear^.Tag := hwSign(HHGear^.dX);
+
+ if HHGear^.dX.isNegative then
+ Gear^.Angle := 4096 - Gear^.Angle;
+ Gear^.doStep := @doStepRCPlaneWork
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepJetpackWork(Gear: PGear);
+var
+ HHGear: PGear;
+ fuel, i: LongInt;
+ move: hwFloat;
+ isUnderwater: Boolean;
+ bubble: PVisualGear;
+begin
+ isUnderwater:= cWaterLine < hwRound(Gear^.Y) + Gear^.Radius;
+ if Gear^.Pos > 0 then
+ dec(Gear^.Pos);
+ AllInactive := false;
+ HHGear := Gear^.Hedgehog^.Gear;
+ //dec(Gear^.Timer);
+ move := _0_2;
+ fuel := 50;
+(*if (HHGear^.Message and gmPrecise) <> 0 then
+ begin
+ move:= _0_02;
+ fuel:= 5;
+ end;*)
+ if HHGear^.Message and gmPrecise <> 0 then
+ HedgehogChAngle(HHGear)
+ else if Gear^.Health > 0 then
+ begin
+ if HHGear^.Message and gmUp <> 0 then
+ begin
+ if (not HHGear^.dY.isNegative) or (HHGear^.Y > -_256) then
+ begin
+ if isUnderwater then
+ begin
+ HHGear^.dY := HHGear^.dY - (move * _0_7);
+ for i:= random(10)+10 downto 0 do
+ begin
+ bubble := AddVisualGear(hwRound(HHGear^.X) - 8 + random(16), hwRound(HHGear^.Y) + 16 + random(8), vgtBubble);
+ if bubble <> nil then
+ bubble^.dY:= random(20)/10+0.1;
+ end
+ end
+ else HHGear^.dY := HHGear^.dY - move;
+ end;
+ dec(Gear^.Health, fuel);
+ Gear^.MsgParam := Gear^.MsgParam or gmUp;
+ Gear^.Timer := GameTicks
+ end;
+ move.isNegative := (HHGear^.Message and gmLeft) <> 0;
+ if (HHGear^.Message and (gmLeft or gmRight)) <> 0 then
+ begin
+ HHGear^.dX := HHGear^.dX + (move * _0_1);
+ if isUnderwater then
+ begin
+ for i:= random(5)+5 downto 0 do
+ begin
+ bubble := AddVisualGear(hwRound(HHGear^.X)+random(8), hwRound(HHGear^.Y) - 8 + random(16), vgtBubble);
+ if bubble <> nil then
+ begin
+ bubble^.dX:= (random(10)/10 + 0.02) * -1;
+ if (move.isNegative) then
+ begin
+ bubble^.X := bubble^.X + 28;
+ bubble^.dX:= bubble^.dX * (-1)
+ end
+ else bubble^.X := bubble^.X - 28;
+ end;
+ end
+ end;
+ dec(Gear^.Health, fuel div 5);
+ Gear^.MsgParam := Gear^.MsgParam or (HHGear^.Message and (gmLeft or gmRight));
+ Gear^.Timer := GameTicks
+ end
+ end;
+
+ // erases them all at once :-/
+ if (Gear^.Timer <> 0) and (GameTicks - Gear^.Timer > 250) then
+ begin
+ Gear^.Timer := 0;
+ Gear^.MsgParam := 0
+ end;
+
+ if Gear^.Health < 0 then
+ Gear^.Health := 0;
+
+ i:= Gear^.Health div 20;
+
+ if (i <> Gear^.Damage) and ((GameTicks and $3F) = 0) then
+ begin
+ Gear^.Damage:= i;
+ //AddCaption('Fuel: '+inttostr(round(Gear^.Health/20))+'%', cWhiteColor, capgrpAmmostate);
+ FreeTexture(Gear^.Tex);
+ Gear^.Tex := RenderStringTex(trmsg[sidFuel] + ': ' + inttostr(i) + '%', cWhiteColor, fntSmall)
+ end;
+
+ if (HHGear^.Message and (gmAttack or gmUp or gmLeft or gmRight) <> 0) and
+ (HHGear^.Message and gmPrecise = 0) then
+ Gear^.State := Gear^.State and (not gsttmpFlag);
+
+ if HHGear^.Message and gmPrecise = 0 then
+ HHGear^.Message := HHGear^.Message and (not (gmUp or gmLeft or gmRight));
+ HHGear^.State := HHGear^.State or gstMoving;
+
+ Gear^.X := HHGear^.X;
+ Gear^.Y := HHGear^.Y;
+
+ if not isUnderWater and hasBorder and ((HHGear^.X < _0)
+ or (hwRound(HHGear^.X) > LAND_WIDTH)) then
+ HHGear^.dY.isNegative:= false;
+
+ if ((Gear^.State and gsttmpFlag) = 0)
+ or (HHGear^.dY < _0) then
+ doStepHedgehogMoving(HHGear);
+
+ if // (Gear^.Health = 0)
+ (HHGear^.Damage <> 0)
+ //or CheckGearDrowning(HHGear)
+ or (cWaterLine + cVisibleWater * 4 < hwRound(HHGear^.Y))
+ or (TurnTimeLeft = 0)
+ // allow brief ground touches - to be fair on this, might need another counter
+ or (((GameTicks and $1FF) = 0) and (not HHGear^.dY.isNegative) and (TestCollisionYwithGear(HHGear, 1) <> 0))
+ or ((Gear^.Message and gmAttack) <> 0) then
+ begin
+ with HHGear^ do
+ begin
+ Message := 0;
+ Active := true;
+ State := State or gstMoving
+ end;
+ DeleteGear(Gear);
+ isCursorVisible := false;
+ ApplyAmmoChanges(HHGear^.Hedgehog^);
+ // if Gear^.Tex <> nil then FreeTexture(Gear^.Tex);
+
+// Gear^.Tex:= RenderStringTex(trmsg[sidFuel] + ': ' + inttostr(round(Gear^.Health / 20)) + '%', cWhiteColor, fntSmall)
+
+//AddCaption(trmsg[sidFuel]+': '+inttostr(round(Gear^.Health/20))+'%', cWhiteColor, capgrpAmmostate);
+ end
+end;
+
+procedure doStepJetpack(Gear: PGear);
+var
+ HHGear: PGear;
+begin
+ Gear^.Pos:= 0;
+ Gear^.doStep := @doStepJetpackWork;
+
+ HHGear := Gear^.Hedgehog^.Gear;
+ FollowGear := HHGear;
+ AfterAttack;
+ with HHGear^ do
+ begin
+ State := State and (not gstAttacking);
+ Message := Message and (not (gmAttack or gmUp or gmPrecise or gmLeft or gmRight));
+
+ if (dY < _0_1) and (dY > -_0_1) then
+ begin
+ Gear^.State := Gear^.State or gsttmpFlag;
+ dY := dY - _0_2
+ end
+ end
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepBirdyDisappear(Gear: PGear);
+begin
+ AllInactive := false;
+ Gear^.Pos := 0;
+ if Gear^.Timer < 2000 then
+ inc(Gear^.Timer, 1)
+ else
+ begin
+ DeleteGear(Gear);
+ end;
+end;
+
+procedure doStepBirdyFly(Gear: PGear);
+var
+ HHGear: PGear;
+ fuel, i: LongInt;
+ move: hwFloat;
+begin
+ HHGear := Gear^.Hedgehog^.Gear;
+ if HHGear = nil then
+ begin
+ DeleteGear(Gear);
+ exit
+ end;
+
+ move := _0_2;
+ fuel := 50;
+
+ if Gear^.Pos > 0 then
+ dec(Gear^.Pos, 1)
+ else if (HHGear^.Message and (gmLeft or gmRight or gmUp)) <> 0 then
+ Gear^.Pos := 500;
+
+ if HHGear^.dX.isNegative then
+ Gear^.Tag := -1
+ else
+ Gear^.Tag := 1;
+
+ if (HHGear^.Message and gmUp) <> 0 then
+ begin
+ if (not HHGear^.dY.isNegative)
+ or (HHGear^.Y > -_256) then
+ HHGear^.dY := HHGear^.dY - move;
+
+ dec(Gear^.Health, fuel);
+ Gear^.MsgParam := Gear^.MsgParam or gmUp;
+ end;
+
+ if (HHGear^.Message and gmLeft) <> 0 then move.isNegative := true;
+ if (HHGear^.Message and (gmLeft or gmRight)) <> 0 then
+ begin
+ HHGear^.dX := HHGear^.dX + (move * _0_1);
+ dec(Gear^.Health, fuel div 5);
+ Gear^.MsgParam := Gear^.MsgParam or (HHGear^.Message and (gmLeft or gmRight));
+ end;
+
+ if Gear^.Health < 0 then
+ Gear^.Health := 0;
+
+ if ((GameTicks and $FF) = 0) and (Gear^.Health < 500) then
+ for i:= ((500-Gear^.Health) div 250) downto 0 do
+ AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtFeather);
+
+ if (HHGear^.Message and gmAttack <> 0) then
+ begin
+ HHGear^.Message := HHGear^.Message and (not gmAttack);
+ if Gear^.FlightTime > 0 then
+ begin
+ AddGear(hwRound(Gear^.X), hwRound(Gear^.Y) + 32, gtEgg, 0, Gear^.dX * _0_5, Gear^.dY, 0);
+ PlaySound(sndBirdyLay);
+ dec(Gear^.FlightTime)
+ end;
+ end;
+
+ if HHGear^.Message and (gmUp or gmPrecise or gmLeft or gmRight) <> 0 then
+ Gear^.State := Gear^.State and (not gsttmpFlag);
+
+ HHGear^.Message := HHGear^.Message and (not (gmUp or gmPrecise or gmLeft or gmRight));
+ HHGear^.State := HHGear^.State or gstMoving;
+
+ Gear^.X := HHGear^.X;
+ Gear^.Y := HHGear^.Y - int2hwFloat(32);
+ // For some reason I need to reapply followgear here, something else grabs it otherwise.
+ // this is probably not needed anymore
+ if not CurrentTeam^.ExtDriven then FollowGear := HHGear;
+
+ if ((Gear^.State and gsttmpFlag) = 0)
+ or (HHGear^.dY < _0) then
+ doStepHedgehogMoving(HHGear);
+
+ if (Gear^.Health = 0)
+ or (HHGear^.Damage <> 0)
+ or CheckGearDrowning(HHGear)
+ or (TurnTimeLeft = 0)
+ // allow brief ground touches - to be fair on this, might need another counter
+ or (((GameTicks and $1FF) = 0) and (not HHGear^.dY.isNegative) and (TestCollisionYwithGear(HHGear, 1) <> 0))
+ or ((Gear^.Message and gmAttack) <> 0) then
+ begin
+ with HHGear^ do
+ begin
+ Message := 0;
+ Active := true;
+ State := State or gstMoving
+ end;
+ Gear^.State := Gear^.State or gstAnimation or gstTmpFlag;
+ if HHGear^.dY < _0 then
+ begin
+ Gear^.dX := HHGear^.dX;
+ Gear^.dY := HHGear^.dY;
+ end;
+ Gear^.Timer := 0;
+ Gear^.doStep := @doStepBirdyDisappear;
+ CurAmmoGear := nil;
+ isCursorVisible := false;
+ AfterAttack;
+ end
+end;
+
+procedure doStepBirdyDescend(Gear: PGear);
+var
+ HHGear: PGear;
+begin
+ if Gear^.Timer > 0 then
+ dec(Gear^.Timer, 1)
+ else if Gear^.Hedgehog^.Gear = nil then
+ begin
+ DeleteGear(Gear);
+ AfterAttack;
+ exit
+ end;
+ HHGear := Gear^.Hedgehog^.Gear;
+ HHGear^.Message := HHGear^.Message and (not (gmUp or gmPrecise or gmLeft or gmRight));
+ if abs(hwRound(HHGear^.Y - Gear^.Y)) > 32 then
+ begin
+ if Gear^.Timer = 0 then
+ Gear^.Y := Gear^.Y + _0_1
+ end
+ else if Gear^.Timer = 0 then
+ begin
+ Gear^.doStep := @doStepBirdyFly;
+ HHGear^.dY := -_0_2
+ end
+end;
+
+procedure doStepBirdyAppear(Gear: PGear);
+begin
+ Gear^.Pos := 0;
+ if Gear^.Timer < 2000 then
+ inc(Gear^.Timer, 1)
+ else
+ begin
+ Gear^.Timer := 500;
+ Gear^.dX := _0;
+ Gear^.dY := _0;
+ Gear^.State := Gear^.State and (not gstAnimation);
+ Gear^.doStep := @doStepBirdyDescend;
+ end
+end;
+
+procedure doStepBirdy(Gear: PGear);
+var
+ HHGear: PGear;
+begin
+ gear^.State := gear^.State or gstAnimation and (not gstTmpFlag);
+ Gear^.doStep := @doStepBirdyAppear;
+
+ if CurrentHedgehog = nil then
+ begin
+ DeleteGear(Gear);
+ exit
+ end;
+
+ HHGear := CurrentHedgehog^.Gear;
+
+ if HHGear^.dX.isNegative then
+ Gear^.Tag := -1
+ else
+ Gear^.Tag := 1;
+ Gear^.Pos := 0;
+ AllInactive := false;
+ FollowGear := HHGear;
+ with HHGear^ do
+ begin
+ State := State and (not gstAttacking);
+ Message := Message and (not (gmAttack or gmUp or gmPrecise or gmLeft or gmRight))
+ end
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepEggWork(Gear: PGear);
+var
+ vg: PVisualGear;
+ i: LongInt;
+begin
+ AllInactive := false;
+ Gear^.dX := Gear^.dX;
+ doStepFallingGear(Gear);
+ // CheckGearDrowning(Gear); // already checked for in doStepFallingGear
+ CalcRotationDirAngle(Gear);
+
+ if (Gear^.State and gstCollision) <> 0 then
+ begin
+ doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 10, Gear^.Hedgehog, EXPLPoisoned, $C0E0FFE0);
+ PlaySound(sndEggBreak);
+ AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtEgg);
+ vg := AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtEgg);
+ if vg <> nil then
+ vg^.Frame := 2;
+
+ for i:= 10 downto 0 do
+ begin
+ vg := AddVisualGear(hwRound(Gear^.X) - 3 + Random(6), hwRound(Gear^.Y) - 3 + Random(6),
+ vgtDust);
+ if vg <> nil then
+ vg^.dX := vg^.dX + (Gear^.dX.QWordValue / 21474836480);
+ end;
+
+ DeleteGear(Gear);
+ exit
+ end;
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doPortalColorSwitch();
+var CurWeapon: PAmmo;
+begin
+ if (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil) and ((CurrentHedgehog^.Gear^.Message and gmSwitch) <> 0) then
+ with CurrentHedgehog^ do
+ if (CurAmmoType = amPortalGun) then
+ begin
+ CurrentHedgehog^.Gear^.Message := CurrentHedgehog^.Gear^.Message and (not gmSwitch);
+
+ CurWeapon:= GetCurAmmoEntry(CurrentHedgehog^);
+ if CurWeapon^.Pos <> 0 then
+ CurWeapon^.Pos := 0
+
+ else
+ CurWeapon^.Pos := 1;
+ end;
+end;
+
+procedure doStepPortal(Gear: PGear);
+var
+ iterator, conPortal: PGear;
+ s, r, nx, ny, ox, oy, poffs, noffs, pspeed, nspeed,
+ resetx, resety, resetdx, resetdy: hwFloat;
+ sx, sy, rh, resetr: LongInt;
+ hasdxy, isbullet, iscake, isCollision: Boolean;
+begin
+ doPortalColorSwitch();
+
+ // destroy portal if ground it was attached too is gone
+ if (Land[hwRound(Gear^.Y), hwRound(Gear^.X)] <= lfAllObjMask)
+ or (Gear^.Timer < 1)
+ or (Gear^.Hedgehog^.Team <> CurrentHedgehog^.Team)
+ or (hwRound(Gear^.Y) > cWaterLine) then
+ begin
+ deleteGear(Gear);
+ EXIT;
+ end;
+
+ if (TurnTimeLeft < 1)
+ or (Gear^.Health < 1) then
+ dec(Gear^.Timer);
+
+ if Gear^.Timer < 10000 then
+ gear^.RenderTimer := true;
+
+ // abort if there is no other portal connected to this one
+ if (Gear^.LinkedGear = nil) then
+ exit;
+ if ((Gear^.LinkedGear^.Tag and 1) = 0) then // or if it's still moving;
+ exit;
+
+ conPortal := Gear^.LinkedGear;
+
+ // check all gears for stuff to port through
+ iterator := nil;
+ while true do
+ begin
+
+ // iterate through GearsList
+ if iterator = nil then
+ iterator := GearsList
+ else
+ iterator := iterator^.NextGear;
+
+ // end of list?
+ if iterator = nil then
+ break;
+
+ // don't port portals or other gear that wouldn't make sense
+ if (iterator^.Kind in [gtPortal, gtRope, gtAirAttack, gtIceGun])
+ or (iterator^.PortalCounter > 32) then
+ continue;
+
+ // don't port hogs on rope
+ // TODO: this will also prevent hogs while falling after rope use from
+ // falling through portals... fix that!
+
+ // check if gear fits through portal
+ if (iterator^.Radius > Gear^.Radius) then
+ continue;
+
+ // this is the max range we accept incoming gears in
+ r := Int2hwFloat(iterator^.Radius+Gear^.Radius);
+
+ // too far away?
+ if (iterator^.X < Gear^.X - r)
+ or (iterator^.X > Gear^.X + r)
+ or (iterator^.Y < Gear^.Y - r)
+ or (iterator^.Y > Gear^.Y + r) then
+ continue;
+
+ hasdxy := (((iterator^.dX.QWordValue <> 0) or (iterator^.dY.QWordValue <> 0)) or ((iterator^.State or gstMoving) = 0));
+
+ // in case the object is not moving, let's asume it's falling towards the portal
+ if not hasdxy then
+ begin
+ if Gear^.Y < iterator^.Y then
+ continue;
+ ox:= Gear^.X - iterator^.X;
+ oy:= Gear^.Y - iterator^.Y;
+ end
+ else
+ begin
+ ox:= iterator^.dX;
+ oy:= iterator^.dY;
+ end;
+
+ // cake will need extra treatment... it's so delicious and moist!
+ iscake:= (iterator^.Kind = gtCake);
+
+ // won't port stuff that does not move towards the front/portal entrance
+ if iscake then
+ begin
+ if not (((iterator^.X - Gear^.X)*ox + (iterator^.Y - Gear^.Y)*oy).isNegative) then
+ continue;
+ end
+ else
+ if not ((Gear^.dX*ox + Gear^.dY*oy).isNegative) then
+ continue;
+
+ isbullet:= (iterator^.Kind in [gtShotgunShot, gtDEagleShot, gtSniperRifleShot, gtSineGunShot]);
+
+ r:= int2hwFloat(iterator^.Radius);
+
+ if not (isbullet or iscake) then
+ begin
+ // wow! good candidate there, let's see if the distance and direction is okay!
+ if hasdxy then
+ begin
+ s := Distance(iterator^.dX, iterator^.dY);
+ // if the resulting distance is 0 skip this gear
+ if s.QWordValue = 0 then
+ continue;
+ s := r / s;
+ ox:= iterator^.X + s * iterator^.dX;
+ oy:= iterator^.Y + s * iterator^.dY;
+ end
+ else
+ begin
+ ox:= iterator^.X;
+ oy:= iterator^.Y + r;
+ end;
+
+ if (hwRound(Distance(Gear^.X-ox,Gear^.Y-oy)) > Gear^.Radius + 1 ) then
+ continue;
+ end;
+
+ // draw bullet trail
+ if isbullet then
+ spawnBulletTrail(iterator);
+
+ // calc gear offset in portal vector direction
+ ox := (iterator^.X - Gear^.X);
+ oy := (iterator^.Y - Gear^.Y);
+ poffs:= (Gear^.dX * ox + Gear^.dY * oy);
+
+ if not isBullet and poffs.isNegative then
+ continue;
+
+ // only port bullets close to the portal
+ if isBullet and (not (hwAbs(poffs) < _3)) then
+ continue;
+
+ //
+ // gears that make it till here will definately be ported
+ //
+ // (but old position/movement vector might be restored in case there's
+ // not enough space on the other side)
+ //
+
+ resetr := iterator^.Radius;
+ resetx := iterator^.X;
+ resety := iterator^.Y;
+ resetdx := iterator^.dX;
+ resetdy := iterator^.dY;
+
+ // create a normal of the portal vector, but ...
+ nx := Gear^.dY;
+ ny := Gear^.dX;
+ // ... decide where the top is based on the hog's direction when firing the portal
+ if Gear^.Elasticity.isNegative then
+ nx.isNegative := (not nx.isNegative)
+ else
+ ny.isNegative := not ny.isNegative;
+
+ // calc gear offset in portal normal vector direction
+ noffs:= (nx * ox + ny * oy);
+
+ if isBullet and (noffs.Round >= Longword(Gear^.Radius)) then
+ continue;
+
+ // avoid gravity related loops of not really moving gear
+ if not (iscake or isbullet)
+ and (Gear^.dY.isNegative)
+ and (conPortal^.dY.isNegative)
+ and ((iterator^.dX.QWordValue + iterator^.dY.QWordValue) < _0_08.QWordValue)
+ and (iterator^.PortalCounter > 0) then
+ continue;
+
+ // calc gear speed along to the vector and the normal vector of the portal
+ if hasdxy then
+ begin
+ pspeed:= (Gear^.dX * iterator^.dX + Gear^.dY * iterator^.dY);
+ nspeed:= (nx * iterator^.dX + ny * iterator^.dY);
+ end
+ else
+ begin
+ pspeed:= hwAbs(cGravity * oy);
+ nspeed:= _0;
+ end;
+
+ // creating normal vector of connected (exit) portal
+ nx := conPortal^.dY;
+ ny := conPortal^.dX;
+ if conPortal^.Elasticity.isNegative then
+ nx.isNegative := (not nx.isNegative)
+ else
+ ny.isNegative := not ny.isNegative;
+
+ // inverse cake's normal movement direction,
+ // as if it just walked through a hole
+ //if iscake then nspeed.isNegative:= not nspeed.isNegative;
+
+//AddFileLog('poffs:'+cstr(poffs)+' noffs:'+cstr(noffs)+' pspeed:'+cstr(pspeed)+' nspeed:'+cstr(nspeed));
+ iterator^.dX := -pspeed * conPortal^.dX + nspeed * nx;
+ iterator^.dY := -pspeed * conPortal^.dY + nspeed * ny;
+
+ // make the gear's exit position close to the portal while
+ // still respecting the movement direction
+
+ // determine the distance (in exit vector direction)
+ // that we want the gear at
+ if iscake then
+ ox:= (r - _0_7)
+ else
+ ox:= (r * _1_5);
+ s:= ox / poffs;
+ poffs:= ox;
+ if (nspeed.QWordValue <> 0)
+ and (pspeed > _0) then
+ noffs:= noffs * s * (nspeed / pspeed);
+
+ // move stuff with high normal offset closer to the portal's center
+ if not isbullet then
+ begin
+ s := hwAbs(noffs) + r - int2hwFloat(Gear^.Radius);
+ if s > _0 then
+ noffs:= noffs - SignAs(s,noffs)
+ end;
+
+ iterator^.X := conPortal^.X + poffs * conPortal^.dX + noffs * nx;
+ iterator^.Y := conPortal^.Y + poffs * conPortal^.dY + noffs * ny;
+
+ if not hasdxy and (not (conPortal^.dY.isNegative)) then
+ begin
+ iterator^.dY:= iterator^.dY + hwAbs(cGravity * (iterator^.Y - conPortal^.Y))
+ end;
+
+ // see if the space on the exit side actually is enough
+
+ if not (isBullet or isCake) then
+ begin
+ // TestCollisionXwithXYShift requires a hwFloat for xShift
+ ox.QWordValue := _1.QWordValue;
+ ox.isNegative := not iterator^.dX.isNegative;
+
+ sx := hwSign(iterator^.dX);
+ sy := hwSign(iterator^.dY);
+
+ if iterator^.Radius > 1 then
+ iterator^.Radius := iterator^.Radius - 1;
+
+ // check front
+ isCollision := TestCollisionY(iterator, sy)
+ or TestCollisionX(iterator, sx);
+
+ if not isCollision then
+ begin
+ // check center area (with half the radius so that the
+ // the square check won't check more pixels than we want to)
+ iterator^.Radius := 1 + resetr div 2;
+ rh := resetr div 4;
+ isCollision := TestCollisionYwithXYShift(iterator, 0, -sy * rh, sy, false)
+ or TestCollisionXwithXYShift(iterator, ox * rh, 0, sx, false);
+ end;
+
+ iterator^.Radius := resetr;
+
+ if isCollision then
+ begin
+ // collision! oh crap! go back!
+ iterator^.X := resetx;
+ iterator^.Y := resety;
+ iterator^.dX := resetdx;
+ iterator^.dY := resetdy;
+ continue;
+ end;
+ end;
+
+ //
+ // You're now officially portaled!
+ //
+
+ // Until loops are reliably broken
+ if iscake then
+ iterator^.PortalCounter:= 33
+ else
+ begin
+ inc(iterator^.PortalCounter);
+ iterator^.Active:= true;
+ iterator^.State:= iterator^.State and (not gstHHHJump) or gstMoving;
+ end;
+
+ // is it worth adding an arcsin table? Just how often would we end up doing something like this?
+ // SYNCED ANGLE UPDATE
+ if iterator^.Kind = gtRCPlane then
+ begin
+ // recycling as temp vars
+ resety.isNegative:= false;
+ resety.QWordValue:= 4294967296 * 112;
+ resetx.isNegative:= false;
+ resetx.QWordValue:= 4294967296 * 35;
+ resetdx.isNegative:= false;
+ resetdx.QWordValue:= 4294967296 * 1152;
+
+ resetdy:=hwAbs(iterator^.dX*4);
+ resetdy:= resetdy + hwPow(resetdy,3)/_6 + _3 * hwPow(resetdy,5) / _40 + _5 * hwPow(resetdy,7) / resety + resetx * hwPow(resetdy,9) / resetdx;
+ iterator^.Angle:= hwRound(resetdy*_2048 / _PI);
+ if not iterator^.dY.isNegative then iterator^.Angle:= 2048-iterator^.Angle;
+ if iterator^.dX.isNegative then iterator^.Angle:= 4096-iterator^.Angle;
+ end
+ // VISUAL USE OF ANGLE ONLY
+ else if (CurAmmoGear <> nil) and (CurAmmoGear^.Kind = gtKamikaze) and (CurAmmoGear^.Hedgehog = iterator^.Hedgehog) then
+ begin
+ iterator^.Angle:= DxDy2AttackAngle(iterator^.dX, iterator^.dY);
+ iterator^.Angle:= 2048-iterator^.Angle;
+ if iterator^.dX.isNegative then iterator^.Angle:= 4096-iterator^.Angle;
+ end;
+
+ if (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil)
+ and (iterator = CurrentHedgehog^.Gear)
+ and (CurAmmoGear <> nil)
+ and (CurAmmoGear^.Kind =gtRope) then
+ CurAmmoGear^.PortalCounter:= 1;
+
+ if not isbullet and (iterator^.State and gstInvisible = 0)
+ and (iterator^.Kind <> gtFlake) then
+ FollowGear := iterator;
+
+ // store X/Y values of exit for net bullet trail
+ if isbullet then
+ begin
+ iterator^.Elasticity:= iterator^.X;
+ iterator^.Friction := iterator^.Y;
+ end;
+
+ if Gear^.Health > 1 then
+ dec(Gear^.Health);
+ end;
+end;
+
+
+
+procedure loadNewPortalBall(oldPortal: PGear; destroyGear: Boolean);
+var
+ CurWeapon: PAmmo;
+begin
+ if CurrentHedgehog <> nil then
+ with CurrentHedgehog^ do
+ begin
+ CurWeapon:= GetCurAmmoEntry(CurrentHedgehog^);
+ if (CurAmmoType = amPortalGun) then
+ begin
+ if not destroyGear then
+ begin
+ // switch color of ball to opposite of oldPortal
+ if (oldPortal^.Tag and 2) = 0 then
+ CurWeapon^.Pos:= 1
+ else
+ CurWeapon^.Pos:= 0;
+ end;
+
+ // make the ball visible
+ CurWeapon^.Timer := 0;
+ end
+ end;
+ if destroyGear then
+ oldPortal^.Timer:= 0;
+end;
+
+procedure doStepMovingPortal_real(Gear: PGear);
+var
+ x, y, tx, ty: LongInt;
+ s: hwFloat;
+begin
+ x := hwRound(Gear^.X);
+ y := hwRound(Gear^.Y);
+ tx := 0;
+ ty := 0;
+ // avoid compiler hints
+
+ if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) and (Land[y, x] > 255) then
+ begin
+ Gear^.State := Gear^.State or gstCollision;
+ Gear^.State := Gear^.State and (not gstMoving);
+
+ if (Land[y, x] and lfBouncy <> 0)
+ or (not CalcSlopeTangent(Gear, x, y, tx, ty, 255))
+ or (DistanceI(tx,ty) < _12) then // reject shots at too irregular terrain
+ begin
+ loadNewPortalBall(Gear, true);
+ EXIT;
+ end;
+
+ // making a normalized normal vector
+ s := _1/DistanceI(tx,ty);
+ Gear^.dX := s * ty;
+ Gear^.dY := -s * tx;
+
+ Gear^.DirAngle := DxDy2Angle(-Gear^.dY,Gear^.dX);
+ if not Gear^.dX.isNegative then
+ Gear^.DirAngle := 180-Gear^.DirAngle;
+
+ if ((Gear^.LinkedGear = nil)
+ or (hwRound(Distance(Gear^.X - Gear^.LinkedGear^.X,Gear^.Y-Gear^.LinkedGear^.Y)) >=Gear^.Radius*2)) then
+ begin
+ loadNewPortalBall(Gear, false);
+ inc(Gear^.Tag);
+ Gear^.doStep := @doStepPortal;
+ end
+ else
+ loadNewPortalBall(Gear, true);
+ end
+
+ else if (y > cWaterLine)
+ or (y < -max(LAND_WIDTH,4096))
+ or (x > 2*max(LAND_WIDTH,4096))
+ or (x < -max(LAND_WIDTH,4096)) then
+ loadNewPortalBall(Gear, true);
+end;
+
+procedure doStepMovingPortal(Gear: PGear);
+begin
+ doPortalColorSwitch();
+ doStepPerPixel(Gear, @doStepMovingPortal_real, true);
+ if (Gear^.Timer < 1)
+ or (Gear^.Hedgehog^.Team <> CurrentHedgehog^.Team) then
+ deleteGear(Gear);
+end;
+
+procedure doStepPortalShot(newPortal: PGear);
+var
+ iterator: PGear;
+ s: hwFloat;
+ CurWeapon: PAmmo;
+begin
+ s:= Distance (newPortal^.dX, newPortal^.dY);
+
+ // Adds the hog speed (only that part in/directly against shot direction)
+ // to the shot speed (which we triple previously btw)
+ // (This is done my projecting the hog movement vector onto the shot movement vector and then adding the resulting length
+ // to the scaler)
+ s := (_2 * s + (newPortal^.dX * CurrentHedgehog^.Gear^.dX + newPortal^.dY * CurrentHedgehog^.Gear^.dY ) / s) / s;
+ newPortal^.dX := newPortal^.dX * s;
+ newPortal^.dY := newPortal^.dY * s;
+
+ newPortal^.LinkedGear := nil;
+
+ if CurrentHedgehog <> nil then
+ with CurrentHedgehog^ do
+ begin
+ CurWeapon:= GetCurAmmoEntry(CurrentHedgehog^);
+ // let's save the HH's dX's direction so we can decide where the "top" of the portal hole
+ newPortal^.Elasticity.isNegative := CurrentHedgehog^.Gear^.dX.isNegative;
+ // when doing a backjump the dx is the opposite of the facing direction
+ if ((Gear^.State and gstHHHJump) <> 0) and (not cArtillery) then
+ newPortal^.Elasticity.isNegative := not newPortal^.Elasticity.isNegative;
+
+ // make portal gun look unloaded
+ if (CurWeapon <> nil) and (CurAmmoType = amPortalGun) then
+ CurWeapon^.Timer := CurWeapon^.Timer or 2;
+
+ iterator := GearsList;
+ while iterator <> nil do
+ begin
+ if (iterator^.Kind = gtPortal) then
+ if (iterator <> newPortal) and (iterator^.Timer > 0) and (iterator^.Hedgehog = CurrentHedgehog) then
+ begin
+ if ((iterator^.Tag and 2) = (newPortal^.Tag and 2)) then
+ begin
+ iterator^.Timer:= 0;
+ end
+ else
+ begin
+ // link portals with each other
+ newPortal^.LinkedGear := iterator;
+ iterator^.LinkedGear := newPortal;
+ iterator^.Health := newPortal^.Health;
+ end;
+ end;
+ iterator^.PortalCounter:= 0;
+ iterator := iterator^.NextGear
+ end;
+
+ if newPortal^.LinkedGear <> nil then
+ begin
+ // This jiggles gears, to ensure a portal connection just placed under a gear takes effect.
+ iterator:= GearsList;
+ while iterator <> nil do
+ begin
+ if not (iterator^.Kind in [gtPortal, gtAirAttack, gtKnife]) and ((iterator^.Hedgehog <> CurrentHedgehog)
+ or ((iterator^.Message and gmAllStoppable) = 0)) then
+ begin
+ iterator^.Active:= true;
+ if iterator^.dY.QWordValue = 0 then
+ iterator^.dY.isNegative:= false;
+ iterator^.State:= iterator^.State or gstMoving;
+ DeleteCI(iterator);
+ //inc(iterator^.dY.QWordValue,10);
+ end;
+ iterator:= iterator^.NextGear
+ end
+ end
+ end;
+ newPortal^.State := newPortal^.State and (not gstCollision);
+ newPortal^.State := newPortal^.State or gstMoving;
+ newPortal^.doStep := @doStepMovingPortal;
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepPiano(Gear: PGear);
+var
+ r0, r1: LongInt;
+ odY: hwFloat;
+begin
+ AllInactive := false;
+ if (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil) and
+ ((CurrentHedgehog^.Gear^.Message and gmSlot) <> 0) then
+ begin
+ case CurrentHedgehog^.Gear^.MsgParam of
+ 0: PlaySound(sndPiano0);
+ 1: PlaySound(sndPiano1);
+ 2: PlaySound(sndPiano2);
+ 3: PlaySound(sndPiano3);
+ 4: PlaySound(sndPiano4);
+ 5: PlaySound(sndPiano5);
+ 6: PlaySound(sndPiano6);
+ 7: PlaySound(sndPiano7);
+ else PlaySound(sndPiano8);
+ end;
+ AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtNote);
+ CurrentHedgehog^.Gear^.MsgParam := 0;
+ CurrentHedgehog^.Gear^.Message := CurrentHedgehog^.Gear^.Message and (not gmSlot);
+ end;
+
+ if (*((Gear^.Pos = 3) and ((GameFlags and gfSolidLand) <> 0)) or*) (Gear^.Pos = 5) then
+ begin
+ Gear^.dY := Gear^.dY + cGravity * 2;
+ Gear^.Y := Gear^.Y + Gear^.dY;
+ if CheckGearDrowning(Gear) then
+ begin
+ Gear^.Y:= Gear^.Y + _50;
+ OnUsedAmmo(CurrentHedgehog^);
+ if CurrentHedgehog^.Gear <> nil then
+ begin
+ // Drown the hedgehog. Could also just delete it, but hey, this gets a caption
+ CurrentHedgehog^.Gear^.Active := true;
+ CurrentHedgehog^.Gear^.X := Gear^.X;
+ CurrentHedgehog^.Gear^.Y := int2hwFloat(cWaterLine+cVisibleWater)+_128;
+ CurrentHedgehog^.Unplaced := false;
+ if TagTurnTimeLeft = 0 then
+ TagTurnTimeLeft:= TurnTimeLeft;
+ TurnTimeLeft:= 0
+ end;
+ ResumeMusic
+ end;
+ exit
+ end;
+
+ odY:= Gear^.dY;
+ doStepFallingGear(Gear);
+
+ if (Gear^.State and gstDrowning) <> 0 then
+ begin
+ Gear^.Y:= Gear^.Y + _50;
+ OnUsedAmmo(CurrentHedgehog^);
+ if CurrentHedgehog^.Gear <> nil then
+ begin
+ // Drown the hedgehog. Could also just delete it, but hey, this gets a caption
+ CurrentHedgehog^.Gear^.Active := true;
+ CurrentHedgehog^.Gear^.X := Gear^.X;
+ CurrentHedgehog^.Gear^.Y := int2hwFloat(cWaterLine+cVisibleWater)+_128;
+ CurrentHedgehog^.Unplaced := false;
+ if TagTurnTimeLeft = 0 then
+ TagTurnTimeLeft:= TurnTimeLeft;
+ TurnTimeLeft:= 0
+ end;
+ ResumeMusic
+ end
+ else if (Gear^.State and gstCollision) <> 0 then
+ begin
+ r0 := GetRandom(21);
+ r1 := GetRandom(21);
+ doMakeExplosion(hwRound(Gear^.X) - 30 - r0, hwRound(Gear^.Y) + 40, 40 + r1, Gear^.Hedgehog, 0);
+ doMakeExplosion(hwRound(Gear^.X) + 30 + r1, hwRound(Gear^.Y) + 40, 40 + r0, Gear^.Hedgehog, 0);
+ doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 80 + r0, Gear^.Hedgehog, EXPLAutoSound);
+ for r0:= 0 to 4 do
+ AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtNote);
+ Gear^.dY := cGravity * 2 - odY;
+ Gear^.Pos := Gear^.Pos + 1;
+ end
+ else
+ Gear^.dY := Gear^.dY + cGravity * 2;
+ // let it fall faster so itdoesn't take too long for the whole attack
+end;
+
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepSineGunShotWork(Gear: PGear);
+var
+ x, y, rX, rY, t, tmp, initHealth: LongInt;
+ oX, oY, ldX, ldY, sdX, sdY, sine, lx, ly, amp: hwFloat;
+ justCollided: boolean;
+begin
+ AllInactive := false;
+ initHealth := Gear^.Health;
+ lX := Gear^.X;
+ lY := Gear^.Y;
+ ldX := Gear^.dX;
+ ldY := Gear^.dY;
+ sdy := _0_5/Distance(Gear^.dX,Gear^.dY);
+ ldX := ldX * sdy;
+ ldY := ldY * sdy;
+ sdY := hwAbs(ldX) + hwAbs(ldY);
+ sdX := _1 - hwAbs(ldX/sdY);
+ sdY := _1 - hwAbs(ldY/sdY);
+ if (ldX.isNegative = ldY.isNegative) then
+ sdY := -sdY;
+
+ // initial angle depends on current GameTicks
+ t := getRandom(4096);
+
+
+ // used for a work-around detection of area that is within land array, but outside borders
+ justCollided := false;
+
+ repeat
+ lX := lX + ldX;
+ lY := lY + ldY;
+ oX := Gear^.X;
+ oY := Gear^.Y;
+ rX := hwRound(oX);
+ rY := hwRound(oY);
+ tmp := t mod 4096;
+ amp := _128 * (_1 - hwSqr(int2hwFloat(Gear^.Health)/initHealth));
+ sine := amp * AngleSin(tmp mod 2048);
+ sine.isNegative := (tmp < 2048);
+ inc(t,Gear^.Health div 313);
+ Gear^.X := lX + (sine * sdX);
+ Gear^.Y := ly + (sine * sdY);
+ Gear^.dX := Gear^.X - oX;
+ Gear^.dY := Gear^.Y - oY;
+
+ x := hwRound(Gear^.X);
+ y := hwRound(Gear^.Y);
+
+ // if borders are on, stop outside land array
+ if hasBorder and (((x and LAND_WIDTH_MASK) <> 0) or ((y and LAND_HEIGHT_MASK) <> 0)) then
+ begin
+ Gear^.Damage := 0;
+ Gear^.Health := 0;
+ end
+ else
+ begin
+ if (rY <= cWaterLine) or (y <= cWaterLine) then
+ begin
+ if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0)
+ and (Land[y, x] <> 0) then
+ begin
+ if justCollided then
+ begin
+ Gear^.Damage := 0;
+ Gear^.Health := 0;
+ end
+ else
+ begin
+ inc(Gear^.Damage,3);
+ justCollided := true;
+ end;
+ end
+ else
+ justCollided := false;
+
+ // kick nearby hogs, dig tunnel and add some fire
+ // if at least 5 collisions occured
+ if Gear^.Damage > 0 then
+ begin
+ DrawExplosion(rX,rY,Gear^.Radius);
+
+ // kick nearby hogs
+ AmmoShove(Gear, 35, 50);
+
+ dec(Gear^.Health, Gear^.Damage);
+ Gear^.Damage := 0;
+
+ // add some fire to the tunnel
+ if getRandom(6) = 0 then
+ begin
+ tmp:= GetRandom(2 * Gear^.Radius);
+ AddGear(x - Gear^.Radius + tmp, y - GetRandom(Gear^.Radius + 1), gtFlame, gsttmpFlag, _0, _0, 0)
+ end
+ end;
+
+ if random(100) = 0 then
+ AddVisualGear(x, y, vgtSmokeTrace);
+ end
+ else dec(Gear^.Health, 5); // if underwater get additional damage
+ end;
+
+ dec(Gear^.Health);
+
+ // decrease bullet size towards the end
+ if (Gear^.Radius > 4) then
+ begin
+ if (Gear^.Health <= (initHealth div 3)) then
+ dec(Gear^.Radius)
+ end
+ else if (Gear^.Radius > 3) then
+ begin
+ if (Gear^.Health <= (initHealth div 4)) then
+ dec(Gear^.Radius)
+ end
+ else if (Gear^.Radius > 2) then begin
+ if (Gear^.Health <= (initHealth div 5)) then
+ dec(Gear^.Radius)
+ end
+ else if (Gear^.Radius > 1) then
+ begin
+ if (Gear^.Health <= (initHealth div 6)) then
+ dec(Gear^.Radius)
+ end;
+
+ until (Gear^.Health <= 0);
+
+ DeleteGear(Gear);
+ AfterAttack;
+end;
+
+procedure doStepSineGunShot(Gear: PGear);
+var
+ HHGear: PGear;
+begin
+ PlaySound(sndSineGun);
+
+ // push the shooting Hedgehog back
+ HHGear := CurrentHedgehog^.Gear;
+ Gear^.dX.isNegative := not Gear^.dX.isNegative;
+ Gear^.dY.isNegative := not Gear^.dY.isNegative;
+ HHGear^.dX := Gear^.dX;
+ HHGear^.dY := Gear^.dY;
+ AmmoShove(Gear, 0, 80);
+ Gear^.dX.isNegative := not Gear^.dX.isNegative;
+ Gear^.dY.isNegative := not Gear^.dY.isNegative;
+
+ Gear^.doStep := @doStepSineGunShotWork;
+ with mobileRecord do
+ if (performRumble <> nil) and (not fastUntilLag) then
+ performRumble(kSystemSoundID_Vibrate);
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepFlamethrowerWork(Gear: PGear);
+var
+ HHGear, flame: PGear;
+ rx, ry, speed: hwFloat;
+ i, gX, gY: LongInt;
+begin
+ AllInactive := false;
+ HHGear := Gear^.Hedgehog^.Gear;
+ HedgehogChAngle(HHGear);
+ gX := hwRound(Gear^.X) + GetLaunchX(amBallgun, hwSign(HHGear^.dX), HHGear^.Angle);
+ gY := hwRound(Gear^.Y) + GetLaunchY(amBallgun, HHGear^.Angle);
+
+ if (GameTicks and $FF) = 0 then
+ begin
+ if (HHGear^.Message and gmRight) <> 0 then
+ begin
+ if HHGear^.dX.isNegative and (Gear^.Tag < 20) then
+ inc(Gear^.Tag)
+ else if Gear^.Tag > 5 then
+ dec(Gear^.Tag);
+ end
+ else if (HHGear^.Message and gmLeft) <> 0 then
+ begin
+ if HHGear^.dX.isNegative and (Gear^.Tag > 5) then
+ dec(Gear^.Tag)
+ else if Gear^.Tag < 20 then
+ inc(Gear^.Tag);
+ end
+ end;
+
+ dec(Gear^.Timer);
+ if Gear^.Timer = 0 then
+ begin
+ dec(Gear^.Health);
+ if (Gear^.Health mod 5) = 0 then
+ begin
+ rx := rndSign(getRandomf * _0_1);
+ ry := rndSign(getRandomf * _0_1);
+ speed := _0_5 * (_10 / Gear^.Tag);
+
+ flame:= AddGear(gx, gy, gtFlame, gstTmpFlag,
+ SignAs(AngleSin(HHGear^.Angle) * speed, HHGear^.dX) + rx,
+ AngleCos(HHGear^.Angle) * ( - speed) + ry, 0);
+ flame^.CollisionMask:= lfNotCurrentMask;
+
+ if (Gear^.Health mod 30) = 0 then
+ begin
+ flame:= AddGear(gx, gy, gtFlame, 0,
+ SignAs(AngleSin(HHGear^.Angle) * speed, HHGear^.dX) + rx,
+ AngleCos(HHGear^.Angle) * ( - speed) + ry, 0);
+ flame^.CollisionMask:= lfNotCurrentMask;
+ end
+ end;
+ Gear^.Timer:= Gear^.Tag
+ end;
+
+ if (Gear^.Health = 0) or ((HHGear^.State and gstHHDriven) = 0) then
+ begin
+ DeleteGear(Gear);
+ AfterAttack
+ end
+ else
+ begin
+ i:= Gear^.Health div 5;
+ if (i <> Gear^.Damage) and ((GameTicks and $3F) = 0) then
+ begin
+ Gear^.Damage:= i;
+ FreeTexture(Gear^.Tex);
+ Gear^.Tex := RenderStringTex(trmsg[sidFuel] + ': ' + inttostr(i) +
+ '%', cWhiteColor, fntSmall)
+ end
+ end
+end;
+
+procedure doStepFlamethrower(Gear: PGear);
+var
+ HHGear: PGear;
+begin
+ HHGear := Gear^.Hedgehog^.Gear;
+ HHGear^.Message := HHGear^.Message and (not (gmUp or gmDown or gmLeft or gmRight));
+ HHGear^.State := HHGear^.State or gstNotKickable;
+ Gear^.doStep := @doStepFlamethrowerWork
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepLandGunWork(Gear: PGear);
+var
+ HHGear, land: PGear;
+ rx, ry, speed: hwFloat;
+ i, gX, gY: LongInt;
+begin
+ AllInactive := false;
+ HHGear := Gear^.Hedgehog^.Gear;
+ HedgehogChAngle(HHGear);
+ gX := hwRound(Gear^.X) + GetLaunchX(amBallgun, hwSign(HHGear^.dX), HHGear^.Angle);
+ gY := hwRound(Gear^.Y) + GetLaunchY(amBallgun, HHGear^.Angle);
+
+ if (GameTicks and $FF) = 0 then
+ begin
+ if (HHGear^.Message and gmRight) <> 0 then
+ begin
+ if HHGear^.dX.isNegative and (Gear^.Tag < 20) then
+ inc(Gear^.Tag)
+ else if Gear^.Tag > 5 then
+ dec(Gear^.Tag);
+ end
+ else if (HHGear^.Message and gmLeft) <> 0 then
+ begin
+ if HHGear^.dX.isNegative and (Gear^.Tag > 5) then
+ dec(Gear^.Tag)
+ else if Gear^.Tag < 20 then
+ inc(Gear^.Tag);
+ end
+ end;
+
+ dec(Gear^.Timer);
+ if Gear^.Timer = 0 then
+ begin
+ dec(Gear^.Health);
+
+ rx := rndSign(getRandomf * _0_1);
+ ry := rndSign(getRandomf * _0_1);
+ speed := (_3 / Gear^.Tag);
+
+ land:= AddGear(gx, gy, gtFlake, gstTmpFlag,
+ SignAs(AngleSin(HHGear^.Angle) * speed, HHGear^.dX) + rx,
+ AngleCos(HHGear^.Angle) * ( - speed) + ry, 0);
+ land^.CollisionMask:= lfNotCurrentMask;
+
+ Gear^.Timer:= Gear^.Tag
+ end;
+
+ if (Gear^.Health = 0) or ((HHGear^.State and gstHHDriven) = 0) or ((HHGear^.Message and gmAttack) <> 0) then
+ begin
+ HHGear^.Message:= HHGear^.Message and (not gmAttack);
+ DeleteGear(Gear);
+ AfterAttack
+ end
+ else
+ begin
+ i:= Gear^.Health div 10;
+ if (i <> Gear^.Damage) and ((GameTicks and $3F) = 0) then
+ begin
+ Gear^.Damage:= i;
+ FreeTexture(Gear^.Tex);
+ Gear^.Tex := RenderStringTex(trmsg[sidFuel] + ': ' + inttostr(i) +
+ '%', cWhiteColor, fntSmall)
+ end
+ end
+end;
+
+procedure doStepLandGun(Gear: PGear);
+var
+ HHGear: PGear;
+begin
+ HHGear := Gear^.Hedgehog^.Gear;
+ HHGear^.Message := HHGear^.Message and (not (gmUp or gmDown or gmLeft or gmRight or gmAttack));
+ HHGear^.State := HHGear^.State or gstNotKickable;
+ Gear^.doStep := @doStepLandGunWork
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepPoisonCloud(Gear: PGear);
+begin
+ if Gear^.Timer = 0 then
+ begin
+ DeleteGear(Gear);
+ exit
+ end;
+ dec(Gear^.Timer);
+ Gear^.X:= Gear^.X + Gear^.dX;
+ Gear^.Y:= Gear^.Y + Gear^.dY;
+ Gear^.dX := Gear^.dX + cWindSpeed / 4;
+ Gear^.dY := Gear^.dY + cGravity / 100;
+ if (GameTicks and $FF) = 0 then
+ doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 20, Gear^.Hedgehog, EXPLDontDraw or EXPLNoGfx or EXPLNoDamage or EXPLDoNotTouchAny or EXPLPoisoned);
+ AllInactive:= false;
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepHammer(Gear: PGear);
+var HHGear, tmp, tmp2: PGear;
+ t: PGearArray;
+ i: LongInt;
+begin
+HHGear:= Gear^.Hedgehog^.Gear;
+HHGear^.State:= HHGear^.State or gstNoDamage;
+DeleteCI(HHGear);
+
+t:= CheckGearsCollision(Gear);
+
+for i:= 5 downto 0 do
+ AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12, vgtDust);
+
+i:= t^.Count;
+while i > 0 do
+ begin
+ dec(i);
+ tmp:= t^.ar[i];
+ if (tmp^.State and gstNoDamage) = 0 then
+ if (tmp^.Kind = gtHedgehog) or (tmp^.Kind = gtMine) or (tmp^.Kind = gtExplosives) then
+ begin
+ //tmp^.State:= tmp^.State or gstFlatened;
+ if not tmp^.Invulnerable then
+ ApplyDamage(tmp, CurrentHedgehog, tmp^.Health div 3, dsUnknown);
+ //DrawTunnel(tmp^.X, tmp^.Y - _1, _0, _0_5, cHHRadius * 6, cHHRadius * 3);
+ tmp2:= AddGear(hwRound(tmp^.X), hwRound(tmp^.Y), gtHammerHit, 0, _0, _0, 0);
+ tmp2^.LinkedGear:= tmp;
+ SetAllToActive
+ end
+ else
+ begin
+ end
+ end;
+
+HHGear^.State:= HHGear^.State and (not gstNoDamage);
+Gear^.Timer:= 250;
+Gear^.doStep:= @doStepIdle
+end;
+
+procedure doStepHammerHitWork(Gear: PGear);
+var
+ i, j, ei: LongInt;
+ HitGear: PGear;
+begin
+ AllInactive := false;
+ HitGear := Gear^.LinkedGear;
+ dec(Gear^.Timer);
+ if (HitGear = nil) or (Gear^.Timer = 0) or ((Gear^.Message and gmDestroy) <> 0) then
+ begin
+ DeleteGear(Gear);
+ exit
+ end;
+
+ if (Gear^.Timer mod 5) = 0 then
+ begin
+ AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12, vgtDust);
+
+ i := hwRound(Gear^.X) - HitGear^.Radius + 2;
+ ei := hwRound(Gear^.X) + HitGear^.Radius - 2;
+ for j := 1 to 4 do DrawExplosion(i - GetRandom(5), hwRound(Gear^.Y) + 6*j, 3);
+ for j := 1 to 4 do DrawExplosion(ei + LongInt(GetRandom(5)), hwRound(Gear^.Y) + 6*j, 3);
+ while i <= ei do
+ begin
+ for j := 1 to 11 do DrawExplosion(i, hwRound(Gear^.Y) + 3*j, 3);
+ inc(i, 1)
+ end;
+
+ if CheckLandValue(hwRound(Gear^.X + Gear^.dX + SignAs(_6,Gear^.dX)), hwRound(Gear^.Y + _1_9)
+ , lfIndestructible) then
+ begin
+ //Gear^.X := Gear^.X + Gear^.dX;
+ Gear^.Y := Gear^.Y + _1_9
+ end;
+ end;
+ if TestCollisionYwithGear(Gear, 1) <> 0 then
+ begin
+ Gear^.dY := _0;
+ SetLittle(HitGear^.dX);
+ HitGear^.dY := _0;
+ end
+ else
+ begin
+ //Gear^.dY := Gear^.dY + cGravity;
+ //Gear^.Y := Gear^.Y + Gear^.dY;
+ if hwRound(Gear^.Y) > cWaterLine then
+ Gear^.Timer := 1
+ end;
+
+ //Gear^.X := Gear^.X + HitGear^.dX;
+ HitGear^.X := Gear^.X;
+ HitGear^.Y := Gear^.Y;
+ SetLittle(HitGear^.dY);
+ HitGear^.Active:= true;
+end;
+
+procedure doStepHammerHit(Gear: PGear);
+var
+ i, y: LongInt;
+ ar: TRangeArray;
+ HHGear: PGear;
+begin
+ i := 0;
+ HHGear := Gear^.Hedgehog^.Gear;
+
+ y := hwRound(Gear^.Y) - cHHRadius * 2;
+ while y < hwRound(Gear^.Y) do
+ begin
+ ar[i].Left := hwRound(Gear^.X) - Gear^.Radius - LongInt(GetRandom(2));
+ ar[i].Right := hwRound(Gear^.X) + Gear^.Radius + LongInt(GetRandom(2));
+ inc(y, 2);
+ inc(i)
+ end;
+
+ DrawHLinesExplosions(@ar, 3, hwRound(Gear^.Y) - cHHRadius * 2, 2, Pred(i));
+ Gear^.dY := HHGear^.dY;
+ DeleteCI(HHGear);
+
+ doStepHammerHitWork(Gear);
+ Gear^.doStep := @doStepHammerHitWork
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepResurrectorWork(Gear: PGear);
+var
+ graves: PGearArrayS;
+ resgear: PGear;
+ hh: PHedgehog;
+ i: LongInt;
+begin
+ if (TurnTimeLeft > 0) then
+ dec(TurnTimeLeft);
+
+ AllInactive := false;
+ hh := Gear^.Hedgehog;
+
+ // no, you can't do that here
+ {DrawCentered(hwRound(hh^.Gear^.X) + WorldDx, hwRound(hh^.Gear^.Y) + WorldDy -
+ cHHRadius - 14 - hh^.HealthTagTex^.h, hh^.HealthTagTex);
+ }
+ (*DrawCircle(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Radius, 1.5, 0, 0, $FF,
+ $FF);*)
+
+ if ((Gear^.Message and gmUp) <> 0) then
+ begin
+ if (GameTicks and $F) <> 0 then
+ exit;
+ end
+ else if (GameTicks and $1FF) <> 0 then
+ exit;
+
+ if Gear^.Power < 45 then
+ begin
+ inc(Gear^.Power);
+ if TestCollisionYwithGear(hh^.Gear, -1) = 0 then
+ hh^.Gear^.Y := hh^.Gear^.Y - _1;
+ end;
+
+ graves := GearsNear(Gear^.X, Gear^.Y, gtGrave, Gear^.Radius);
+
+ if graves.size = 0 then
+ begin
+ StopSoundChan(Gear^.SoundChannel);
+ Gear^.Timer := 250;
+ Gear^.doStep := @doStepIdle;
+ exit;
+ end;
+
+ if ((Gear^.Message and gmAttack) <> 0) and (hh^.Gear^.Health > 0) and (TurnTimeLeft > 0) then
+ begin
+ if LongInt(graves.size) <= Gear^.Tag then Gear^.Tag:= 0;
+ dec(hh^.Gear^.Health);
+ if (hh^.Gear^.Health = 0) and (hh^.Gear^.Damage = 0) then
+ hh^.Gear^.Damage:= 1;
+ RenderHealth(hh^);
+ RecountTeamHealth(hh^.Team);
+ inc(graves.ar^[Gear^.Tag]^.Health);
+ inc(Gear^.Tag)
+{-for i:= 0 to High(graves) do begin
+ if hh^.Gear^.Health > 0 then begin
+ dec(hh^.Gear^.Health);
+ inc(graves[i]^.Health);
+ end;
+ end; -}
+ end
+ else
+ begin
+ // now really resurrect the hogs with the hp saved in the graves
+ for i:= 0 to graves.size - 1 do
+ if graves.ar^[i]^.Health > 0 then
+ begin
+ resgear := AddGear(hwRound(graves.ar^[i]^.X), hwRound(graves.ar^[i]^.Y), gtHedgehog, gstWait, _0, _0, 0);
+ resgear^.Hedgehog := graves.ar^[i]^.Hedgehog;
+ resgear^.Health := graves.ar^[i]^.Health;
+ PHedgehog(graves.ar^[i]^.Hedgehog)^.Gear := resgear;
+ graves.ar^[i]^.Message:= graves.ar^[i]^.Message or gmDestroy;
+ graves.ar^[i]^.Active:= true;
+ RenderHealth(resgear^.Hedgehog^);
+ RecountTeamHealth(resgear^.Hedgehog^.Team);
+ resgear^.Hedgehog^.Effects[heResurrected]:= 1;
+ // only make hat-less hedgehogs look like zombies, preserve existing hats
+
+ if resgear^.Hedgehog^.Hat = 'NoHat' then
+ LoadHedgehogHat(resgear^.Hedgehog^, 'Reserved/Zombie');
+ end;
+
+ hh^.Gear^.dY := _0;
+ hh^.Gear^.dX := _0;
+ doStepHedgehogMoving(hh^.Gear);
+ StopSoundChan(Gear^.SoundChannel);
+ Gear^.Timer := 250;
+ Gear^.doStep := @doStepIdle;
+ end
+ //if hh^.Gear^.Health = 0 then doStepHedgehogFree(hh^.Gear);
+end;
+
+procedure doStepResurrector(Gear: PGear);
+var
+ graves: PGearArrayS;
+ hh: PHedgehog;
+ i: LongInt;
+begin
+ AllInactive := false;
+ graves := GearsNear(Gear^.X, Gear^.Y, gtGrave, Gear^.Radius);
+
+ if graves.size > 0 then
+ begin
+ hh := Gear^.Hedgehog;
+ for i:= 0 to graves.size - 1 do
+ begin
+ PHedgehog(graves.ar^[i]^.Hedgehog)^.Gear := nil;
+ graves.ar^[i]^.Health := 0;
+ end;
+ Gear^.doStep := @doStepResurrectorWork;
+ if ((Gear^.Message and gmAttack) <> 0) and (hh^.Gear^.Health > 0) and (TurnTimeLeft > 0) then
+ begin
+ if LongInt(graves.size) <= Gear^.Tag then Gear^.Tag:= 0;
+ dec(hh^.Gear^.Health);
+ if (hh^.Gear^.Health = 0) and (hh^.Gear^.Damage = 0) then
+ hh^.Gear^.Damage:= 1;
+ RenderHealth(hh^);
+ RecountTeamHealth(hh^.Team);
+ inc(graves.ar^[Gear^.Tag]^.Health);
+ inc(Gear^.Tag)
+ end
+ end
+ else
+ begin
+ StopSoundChan(Gear^.SoundChannel);
+ Gear^.Timer := 250;
+ Gear^.doStep := @doStepIdle;
+ end
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepNapalmBomb(Gear: PGear);
+var
+ i, gX, gY: LongInt;
+ dX, dY: hwFloat;
+begin
+ AllInactive := false;
+ doStepFallingGear(Gear);
+ if (Gear^.Timer > 0) and ((Gear^.State and gstCollision) <> 0) then
+ begin
+ doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 10, Gear^.Hedgehog, EXPLAutoSound);
+ gX := hwRound(Gear^.X);
+ gY := hwRound(Gear^.Y);
+ for i:= 0 to 10 do
+ begin
+ dX := AngleCos(i * 2) * ((_0_1*(i div 5))) * (GetRandomf + _1);
+ dY := AngleSin(i * 8) * _0_5 * (GetRandomf + _1);
+ AddGear(gX, gY, gtFlame, 0, dX, dY, 0);
+ AddGear(gX, gY, gtFlame, 0, dX, -dY, 0);
+ AddGear(gX, gY, gtFlame, 0, -dX, dY, 0);
+ AddGear(gX, gY, gtFlame, 0, -dX, -dY, 0);
+ end;
+ DeleteGear(Gear);
+ exit
+ end;
+ if (Gear^.Timer = 0) then
+ begin
+ doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 10, Gear^.Hedgehog, EXPLAutoSound);
+ for i:= -19 to 19 do
+ FollowGear := AddGear(hwRound(Gear^.X) + i div 3, hwRound(Gear^.Y), gtFlame, 0, _0_001 * i, _0, 0);
+ DeleteGear(Gear);
+ exit
+ end;
+ if (GameTicks and $3F) = 0 then
+ AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace);
+ dec(Gear^.Timer)
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepStructure(Gear: PGear);
+var
+ x, y: LongInt;
+ HH: PHedgehog;
+ t: PGear;
+begin
+ HH:= Gear^.Hedgehog;
+
+ if (Gear^.State and gstMoving) <> 0 then
+ begin
+ AddCI(Gear);
+ Gear^.dX:= _0;
+ Gear^.dY:= _0;
+ Gear^.State:= Gear^.State and (not gstMoving);
+ end;
+
+ dec(Gear^.Health, Gear^.Damage);
+ Gear^.Damage:= 0;
+
+ if Gear^.Pos = 1 then
+ begin
+ AddCI(Gear);
+ AfterAttack;
+ if Gear = CurAmmoGear then
+ CurAmmoGear:= nil;
+ if HH^.Gear <> nil then
+ HideHog(HH);
+ Gear^.Pos:= 2
+ end;
+
+ if Gear^.Pos = 2 then
+ begin
+ if ((GameTicks mod 100) = 0) and (Gear^.Timer < 1000) then
+ begin
+ if (Gear^.Timer mod 10) = 0 then
+ begin
+ DeleteCI(Gear);
+ Gear^.Y:= Gear^.Y - _0_5;
+ AddCI(Gear);
+ end;
+ inc(Gear^.Timer);
+ end;
+ if Gear^.Tag <= TotalRounds then
+ Gear^.Pos:= 3;
+ end;
+
+ if Gear^.Pos = 3 then
+ if Gear^.Timer < 1000 then
+ begin
+ if (Gear^.Timer mod 10) = 0 then
+ begin
+ DeleteCI(Gear);
+ Gear^.Y:= Gear^.Y - _0_5;
+ AddCI(Gear);
+ end;
+ inc(Gear^.Timer);
+ end
+ else
+ begin
+ if HH^.GearHidden <> nil then
+ RestoreHog(HH);
+ Gear^.Pos:= 4;
+ end;
+
+ if Gear^.Pos = 4 then
+ if ((GameTicks mod 1000) = 0) and ((GameFlags and gfInvulnerable) = 0) then
+ begin
+ t:= GearsList;
+ while t <> nil do
+ begin
+ if (t^.Kind = gtHedgehog) and (t^.Hedgehog^.Team^.Clan = HH^.Team^.Clan) then
+ t^.Invulnerable:= true;
+ t:= t^.NextGear;
+ end;
+ end;
+
+ if Gear^.Health <= 0 then
+ begin
+ if HH^.GearHidden <> nil then
+ RestoreHog(HH);
+
+ x := hwRound(Gear^.X);
+ y := hwRound(Gear^.Y);
+
+ DeleteCI(Gear);
+ DeleteGear(Gear);
+
+ doMakeExplosion(x, y, 50, CurrentHedgehog, EXPLAutoSound);
+ end;
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+(*
+ TARDIS needs
+ Warp in. Pos = 1
+ Pause. Pos = 2
+ Hide gear (TARDIS hedgehog was nil)
+ Warp out. Pos = 3
+ ... idle active for some time period ... Pos = 4
+ Warp in. Pos = 1
+ Pause. Pos = 2
+ Restore gear (TARDIS hedgehog was not nil)
+ Warp out. Pos = 3
+*)
+
+procedure doStepTardisWarp(Gear: PGear);
+var HH: PHedgehog;
+ i,j,cnt: LongWord;
+begin
+HH:= Gear^.Hedgehog;
+if Gear^.Pos = 2 then
+ begin
+ StopSoundChan(Gear^.SoundChannel);
+ if (Gear^.Timer = 0) then
+ begin
+ if (HH^.Gear <> nil) and (HH^.Gear^.State and gstInvisible = 0) then
+ begin
+ AfterAttack;
+ if Gear = CurAmmoGear then CurAmmoGear := nil;
+ if (HH^.Gear^.Damage = 0) and (HH^.Gear^.Health > 0) and
+ ((Gear^.State and (gstMoving or gstHHDeath or gstHHGone)) = 0) then
+ HideHog(HH)
+ end
+ //else if (HH^.Gear <> nil) and (HH^.Gear^.State and gstInvisible <> 0) then
+ else if (HH^.GearHidden <> nil) then// and (HH^.Gear^.State and gstInvisible <> 0) then
+ RestoreHog(HH)
+ end;
+
+ inc(Gear^.Timer);
+ if (Gear^.Timer > 2000) and ((GameTicks mod 2000) = 1000) then
+ begin
+ Gear^.SoundChannel := LoopSound(sndTardis);
+ Gear^.Pos:= 3
+ end
+ end;
+
+if (Gear^.Pos = 1) and (GameTicks and $1F = 0) and (Gear^.Power < 255) then
+ begin
+ inc(Gear^.Power);
+ if (Gear^.Power = 172) and (HH^.Gear <> nil) and
+ (HH^.Gear^.Damage = 0) and (HH^.Gear^.Health > 0) and
+ ((HH^.Gear^.State and (gstMoving or gstHHDeath or gstHHGone)) = 0) then
+ with HH^.Gear^ do
+ begin
+ State:= State or gstAnimation;
+ Tag:= 2;
+ Timer:= 0;
+ Pos:= 0
+ end
+ end;
+if (Gear^.Pos = 3) and (GameTicks and $1F = 0) and (Gear^.Power > 0) then
+ dec(Gear^.Power);
+if (Gear^.Pos = 1) and (Gear^.Power = 255) and ((GameTicks mod 2000) = 1000) then
+ Gear^.Pos:= 2;
+if (Gear^.Pos = 3) and (Gear^.Power = 0) then
+ begin
+ StopSoundChan(Gear^.SoundChannel);
+ if HH^.GearHidden = nil then
+ begin
+ DeleteGear(Gear);
+ exit
+ end;
+ Gear^.Pos:= 4;
+ // This condition might need tweaking
+ Gear^.Timer:= GetRandom(cHedgehogTurnTime*TeamsCount)+cHedgehogTurnTime
+ end;
+
+if (Gear^.Pos = 4) then
+ begin
+ cnt:= 0;
+ for j:= 0 to Pred(HH^.Team^.Clan^.TeamsNumber) do
+ for i:= 0 to Pred(HH^.Team^.Clan^.Teams[j]^.HedgehogsNumber) do
+ if (HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear <> nil)
+ and ((HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear^.State and gstDrowning) = 0)
+ and (HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear^.Health > HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear^.Damage) then
+ inc(cnt);
+ if (cnt = 0) or SuddenDeathDmg or (Gear^.Timer = 0) then
+ begin
+ if HH^.GearHidden <> nil then
+ FindPlace(HH^.GearHidden, false, 0, LAND_WIDTH,true);
+
+ if HH^.GearHidden <> nil then
+ begin
+ Gear^.X:= HH^.GearHidden^.X;
+ Gear^.Y:= HH^.GearHidden^.Y;
+ end;
+ Gear^.Timer:= 0;
+
+ if (HH^.GearHidden <> nil) and (cnt = 0) then // do an emergency jump back in this case. the team needs you!
+ begin
+ AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtExplosion);
+ Gear^.Pos:= 2;
+ Gear^.Power:= 255;
+ end
+ else begin
+ Gear^.SoundChannel := LoopSound(sndTardis);
+ Gear^.Pos:= 1;
+ Gear^.Power:= 0;
+ end
+ end
+ else if (CurrentHedgehog^.Team^.Clan = Gear^.Hedgehog^.Team^.Clan) then dec(Gear^.Timer)
+ end;
+
+end;
+
+procedure doStepTardis(Gear: PGear);
+var i,j,cnt: LongWord;
+ HH: PHedgehog;
+begin
+(*
+ Conditions for not activating.
+ 1. Hog is last of his clan
+ 2. Sudden Death is in play
+ 3. Hog is a king
+*)
+ HH:= Gear^.Hedgehog;
+ if HH^.Gear <> nil then
+ if (HH^.Gear = nil) or (HH^.King) or (SuddenDeathDmg) then
+ begin
+ if HH^.Gear <> nil then
+ begin
+ HH^.Gear^.Message := HH^.Gear^.Message and (not gmAttack);
+ HH^.Gear^.State:= HH^.Gear^.State and (not gstAttacking);
+ end;
+ PlaySound(sndDenied);
+ DeleteGear(gear);
+ exit
+ end;
+ cnt:= 0;
+ for j:= 0 to Pred(HH^.Team^.Clan^.TeamsNumber) do
+ for i:= 0 to Pred(HH^.Team^.Clan^.Teams[j]^.HedgehogsNumber) do
+ if (HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear <> nil)
+ and ((HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear^.State and gstDrowning) = 0)
+ and (HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear^.Health > HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear^.Damage) then
+ inc(cnt);
+ if cnt < 2 then
+ begin
+ if HH^.Gear <> nil then
+ begin
+ HH^.Gear^.Message := HH^.Gear^.Message and (not gmAttack);
+ HH^.Gear^.State:= HH^.Gear^.State and (not gstAttacking);
+ end;
+ PlaySound(sndDenied);
+ DeleteGear(gear);
+ exit
+ end;
+ Gear^.SoundChannel := LoopSound(sndTardis);
+ Gear^.doStep:= @doStepTardisWarp
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+
+(*
+WIP. The ice gun will have the following effects. It has been proposed by sheepluva that it take the appearance of a large freezer
+spewing ice cubes. The cubes will be visual gears only. The scatter from them and the impact snow dust should help hide imprecisions in things like the GearsNear effect.
+For now we assume a "ray" like a deagle projected out from the gun.
+All these effects assume the ray's angle is not changed and that the target type was unchanged over a number of ticks. This is a simplifying assumption for "gun was applying freezing effect to the same target".
+ * When fired at water a layer of ice textured land is added above the water.
+ * When fired at non-ice land (land and lfLandMask and not lfIce) the land is overlaid with a thin layer of ice textured land around that point (say, 1 or 2px into land, 1px above). For attractiveness, a slope would probably be needed.
+ * When fired at a hog (land and $00FF <> 0), while the hog is targetted, the hog's state is set to frozen. As long as the gun is on the hog, a frozen hog sprite creeps up from the feet to the head. If the effect is interrupted before reaching the top, the freezing state is cleared.
+A frozen hog will animate differently. To be decided, but possibly in a similar fashion to a grave when it comes to explosions. The hog might (possibly) not be damaged by explosions. This might make freezing potentially useful for friendlies in a bad position. It might be better to allow damage though.
+A frozen hog stays frozen for a certain number of turns. Each turn the frozen overlay becomes fainter, until it fades and the hog animates normally again.
+*)
+
+
+procedure updateFuel(Gear: PGear);
+var
+ t:LongInt;
+begin
+ t:= Gear^.Health div 10;
+ if (t <> Gear^.Damage) and ((GameTicks and $3F) = 0) then
+ begin
+ Gear^.Damage:= t;
+ FreeTexture(Gear^.Tex);
+ Gear^.Tex := RenderStringTex(trmsg[sidFuel] + ': ' + inttostr(t) +
+ '%', cWhiteColor, fntSmall)
+ end;
+ if Gear^.Message and (gmUp or gmDown) <> 0 then
+ begin
+ StopSoundChan(Gear^.SoundChannel);
+ Gear^.SoundChannel:= -1;
+ if GameTicks mod 40 = 0 then dec(Gear^.Health)
+ end
+ else
+ begin
+ if Gear^.SoundChannel = -1 then
+ Gear^.SoundChannel := LoopSound(sndIceBeam);
+ if GameTicks mod 10 = 0 then dec(Gear^.Health)
+ end
+end;
+
+
+procedure updateTarget(Gear:PGear; newX, newY:HWFloat);
+// var
+// iter:PGear;
+begin
+ with Gear^ do
+ begin
+ dX:= newX;
+ dY:= newY;
+ Pos:= 0;
+ Target.X:= NoPointX;
+ LastDamage:= nil;
+ X:= Hedgehog^.Gear^.X;
+ Y:= Hedgehog^.Gear^.Y;
+ end;
+end;
+
+procedure doStepIceGun(Gear: PGear);
+const iceWaitCollision = 0;
+const iceCollideWithGround = 1;
+//const iceWaitNextTarget:Longint = 2;
+//const iceCollideWithHog:Longint = 4;
+const iceCollideWithWater = 5;
+//const waterFreezingTime:Longint = 500;
+const groundFreezingTime = 1000;
+const iceRadius = 32;
+const iceHeight = 40;
+var
+ HHGear, iter: PGear;
+ landRect: TSDL_Rect;
+ ndX, ndY: hwFloat;
+ i, t, gX, gY: LongInt;
+ hogs: PGearArrayS;
+ vg: PVisualGear;
+begin
+ HHGear := Gear^.Hedgehog^.Gear;
+ if (Gear^.Message and gmAttack <> 0) or (HHGear = nil) or ((HHGear^.State and gstHHDriven) = 0) or (HHGear^.dX.QWordValue > 4294967) then
+ begin
+ StopSoundChan(Gear^.SoundChannel);
+ DeleteGear(Gear);
+ AfterAttack;
+ exit
+ end;
+ updateFuel(Gear);
+
+ with Gear^ do
+ begin
+ HedgehogChAngle(HHGear);
+ ndX:= SignAs(AngleSin(HHGear^.Angle), HHGear^.dX) * _4;
+ ndY:= -AngleCos(HHGear^.Angle) * _4;
+ if (ndX <> dX) or (ndY <> dY) or
+ ((Target.X <> NoPointX) and (Target.X and LAND_WIDTH_MASK = 0) and
+ (Target.Y and LAND_HEIGHT_MASK = 0) and ((Land[Target.Y, Target.X] = 0))) then
+ begin
+ updateTarget(Gear, ndX, ndY);
+ Timer := iceWaitCollision;
+ end
+ else
+ begin
+ X:= X + dX;
+ Y:= Y + dY;
+ gX:= hwRound(X);
+ gY:= hwRound(Y);
+ if Target.X = NoPointX then t:= hwRound(hwSqr(X-HHGear^.X)+hwSqr(Y-HHGear^.Y));
+
+ if Target.X <> NoPointX then
+ begin
+ CheckCollision(Gear);
+ if (State and gstCollision) <> 0 then
+ begin
+ if Timer = iceWaitCollision then
+ begin
+ Timer := iceCollideWithGround;
+ Power := GameTicks;
+ end
+ end
+ else if (target.y >= cWaterLine) then
+ begin
+ if Timer = iceWaitCollision then
+ begin
+ Timer := iceCollideWithWater;
+ Power := GameTicks;
+ end;
+ end;
+
+ if (abs(gX-Target.X) < 2) and (abs(gY-Target.Y) < 2) then
+ begin
+ X:= HHGear^.X;
+ Y:= HHGear^.Y
+ end;
+
+ if (Timer = iceCollideWithGround) and ((GameTicks - Power) > groundFreezingTime) then
+ begin
+ FillRoundInLand(target.x, target.y, iceRadius, icePixel);
+ landRect.x := min(max(target.x - iceRadius, 0), LAND_WIDTH - 1);
+ landRect.y := min(max(target.y - iceRadius, 0), LAND_HEIGHT - 1);
+ landRect.w := min(2*iceRadius, LAND_WIDTH - landRect.x - 1);
+ landRect.h := min(2*iceRadius, LAND_HEIGHT - landRect.y - 1);
+ UpdateLandTexture(landRect.x, landRect.w, landRect.y, landRect.h, true);
+
+ // Freeze nearby mines/explosives/cases too
+ iter := GearsList;
+ while iter <> nil do
+ begin
+ if (iter^.State and gstFrozen = 0) and
+ ((iter^.Kind = gtExplosives) or (iter^.Kind = gtCase) or (iter^.Kind = gtMine)) and
+ (abs(iter^.X.Round-target.x)+abs(iter^.Y.Round-target.y)+2<2*iceRadius) and (Distance(iter^.X-int2hwFloat(target.x),iter^.Y-int2hwFloat(target.y))<int2hwFloat(iceRadius*2)) then
+ begin
+ for t:= 0 to 5 do
+ begin
+ vg:= AddVisualGear(hwRound(iter^.X)+random(4)-8, hwRound(iter^.Y)+random(8), vgtDust, 1);
+ if vg <> nil then
+ begin
+ i:= random(100) + 155;
+ vg^.Tint:= (i shl 24) or (i shl 16) or ($FF shl 8) or (random(200) + 55);
+ vg^.Angle:= random(360);
+ vg^.dx:= 0.001 * random(80);
+ vg^.dy:= 0.001 * random(80)
+ end
+ end;
+ PlaySound(sndHogFreeze);
+ if iter^.Kind = gtMine then // dud mine block
+ begin
+ iter^.State:= iter^.State or gstFrozen;
+ vg:= AddVisualGear(hwRound(iter^.X) - 4 + Random(8), hwRound(iter^.Y) - 4 - Random(4), vgtSmoke);
+ if vg <> nil then
+ vg^.Scale:= 0.5;
+ PlaySound(sndVaporize);
+ iter^.Health := 0;
+ iter^.Damage := 0;
+ iter^.State := iter^.State and (not gstAttacking)
+ end
+ else if iter^.Kind = gtCase then
+ begin
+ DeleteCI(iter);
+ iter^.State:= iter^.State or gstFrozen;
+ AddCI(iter)
+ end
+ else // gtExplosives
+ begin
+ iter^.State:= iter^.State or gstFrozen;
+ iter^.Health:= iter^.Health + cBarrelHealth
+ end
+ end;
+ iter:= iter^.NextGear
+ end;
+
+ // FillRoundInLandWithIce(Target.X, Target.Y, iceRadius);
+ SetAllHHToActive;
+ Timer := iceWaitCollision;
+ end;
+
+ if (Timer = iceCollideWithWater) and ((GameTicks - Power) > groundFreezingTime) then
+ begin
+ PlaySound(sndHogFreeze);
+ DrawIceBreak(Target.X, cWaterLine - iceHeight, iceRadius, iceHeight);
+ SetAllHHToActive;
+ Timer := iceWaitCollision;
+ end;
+(*
+ Any ideas for something that would look good here?
+ if (Target.X <> NoPointX) and ((Timer = iceCollideWithGround) or (Timer = iceCollideWithWater)) and (GameTicks mod max((groundFreezingTime-((GameTicks - Power)*2)),2) = 0) then //and CheckLandValue(Target.X, Target.Y, lfIce) then
+ begin
+ vg:= AddVisualGear(Target.X+random(20)-10, Target.Y+random(40)-10, vgtDust, 1);
+ if vg <> nil then
+ begin
+ i:= random(100) + 155;
+ vg^.Tint:= IceColor or $FF;
+ vg^.Angle:= random(360);
+ vg^.dx:= 0.001 * random(80);
+ vg^.dy:= 0.001 * random(80)
+ end
+ end;
+*)
+
+// freeze nearby hogs
+ hogs := GearsNear(int2hwFloat(Target.X), int2hwFloat(Target.Y), gtHedgehog, Gear^.Radius*2);
+ if hogs.size > 0 then
+ for i:= 0 to hogs.size - 1 do
+ if hogs.ar^[i] <> HHGear then
+ if GameTicks mod 5 = 0 then
+ begin
+ hogs.ar^[i]^.Active:= true;
+ if hogs.ar^[i]^.Hedgehog^.Effects[heFrozen] < 256 then
+ hogs.ar^[i]^.Hedgehog^.Effects[heFrozen] := hogs.ar^[i]^.Hedgehog^.Effects[heFrozen] + 1
+ else if hogs.ar^[i]^.Hedgehog^.Effects[heFrozen] = 256 then
+ begin
+ hogs.ar^[i]^.Hedgehog^.Effects[heFrozen]:= 200000-1;//cHedgehogTurnTime + cReadyDelay
+ PlaySound(sndHogFreeze);
+ end;
+ end;
+ inc(Pos)
+ end
+ else if (t > 400) and ((gY > cWaterLine) or
+ (((gX and LAND_WIDTH_MASK = 0) and (gY and LAND_HEIGHT_MASK = 0))
+ and (Land[gY, gX] <> 0))) then
+ begin
+ Target.X:= gX;
+ Target.Y:= gY;
+ X:= HHGear^.X;
+ Y:= HHGear^.Y
+ end;
+ if (gX > max(LAND_WIDTH,4096)*2) or
+ (gX < -max(LAND_WIDTH,4096)) or
+ (gY < -max(LAND_HEIGHT,4096)) or
+ (gY > max(LAND_HEIGHT,4096)+512) then
+ begin
+ //X:= HHGear^.X;
+ //Y:= HHGear^.Y
+ Target.X:= gX;
+ Target.Y:= gY;
+ end
+ end
+ end;
+end;
+
+procedure doStepAddAmmo(Gear: PGear);
+var a: TAmmoType;
+ gi: PGear;
+begin
+if Gear^.Timer > 0 then dec(Gear^.Timer)
+else
+ begin
+ if Gear^.Pos = posCaseUtility then
+ a:= GetUtility(Gear^.Hedgehog)
+ else
+ a:= GetAmmo(Gear^.Hedgehog);
+ CheckSum:= CheckSum xor GameTicks;
+ gi := GearsList;
+ while gi <> nil do
+ begin
+ with gi^ do CheckSum:= CheckSum xor X.round xor X.frac xor dX.round xor dX.frac xor Y.round xor Y.frac xor dY.round xor dY.frac;
+ AddRandomness(CheckSum);
+ if gi^.Kind = gtGenericFaller then gi^.State:= gi^.State and not gstTmpFlag;
+ gi := gi^.NextGear
+ end;
+ AddPickup(Gear^.Hedgehog^, a, Gear^.Power, hwRound(Gear^.X), hwRound(Gear^.Y));
+ DeleteGear(Gear)
+ end;
+end;
+
+procedure doStepGenericFaller(Gear: PGear);
+begin
+if Gear^.Timer < $FFFFFFFF then
+ if Gear^.Timer > 0 then
+ dec(Gear^.Timer)
+ else
+ begin
+ DeleteGear(Gear);
+ exit
+ end;
+if (Gear^.State and gstTmpFlag <> 0) or (GameTicks and $7 = 0) then
+ begin
+ doStepFallingGear(Gear);
+ if (Gear^.State and gstInvisible <> 0) and (GameTicks and $FF = 0) and (hwRound(Gear^.X) < LongInt(leftX)) or (hwRound(Gear^.X) > LongInt(rightX)) or (hwRound(Gear^.Y) < LongInt(topY)) then
+ begin
+ Gear^.X:= int2hwFloat(GetRandom(rightX-leftX)+leftX);
+ Gear^.Y:= int2hwFloat(GetRandom(LAND_HEIGHT-topY)+topY);
+ Gear^.dX:= _90-(GetRandomf*_360);
+ Gear^.dY:= _90-(GetRandomf*_360)
+ end;
+ end
+end;
+
+procedure doStepCreeper(Gear: PGear);
+var hogs: PGearArrayS;
+ HHGear: PGear;
+ tdX: hwFloat;
+ dir: LongInt;
+begin
+doStepFallingGear(Gear);
+if Gear^.Timer > 0 then dec(Gear^.Timer);
+// creeper sleep phase
+if (Gear^.Hedgehog = nil) and (Gear^.Timer > 0) then exit;
+
+if Gear^.Hedgehog <> nil then HHGear:= Gear^.Hedgehog^.Gear
+else HHGear:= nil;
+
+// creeper boom phase
+if (Gear^.State and gstTmpFlag <> 0) then
+ begin
+ if (Gear^.Timer = 0) then
+ begin
+ doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 300, CurrentHedgehog, EXPLAutoSound);
+ DeleteGear(Gear)
+ end;
+ // ssssss he essssscaped
+ if (Gear^.Timer > 250) and ((HHGear = nil) or
+ (((abs(HHGear^.X.Round-Gear^.X.Round) + abs(HHGear^.Y.Round-Gear^.Y.Round) + 2) > 180) and
+ (Distance(HHGear^.X-Gear^.X,HHGear^.Y-Gear^.Y) > _180))) then
+ begin
+ Gear^.State:= Gear^.State and (not gstTmpFlag);
+ Gear^.Timer:= 0
+ end;
+ exit
+ end;
+
+// Search out a new target, as target seek time has expired, target is dead, target is out of range, or we did not have a target
+if (HHGear = nil) or (Gear^.Timer = 0) or
+ (((abs(HHGear^.X.Round-Gear^.X.Round) + abs(HHGear^.Y.Round-Gear^.Y.Round) + 2) > Gear^.Angle) and
+ (Distance(HHGear^.X-Gear^.X,HHGear^.Y-Gear^.Y) > int2hwFloat(Gear^.Angle)))
+ then
+ begin
+ hogs := GearsNear(Gear^.X, Gear^.Y, gtHedgehog, Gear^.Angle);
+ if hogs.size > 1 then
+ Gear^.Hedgehog:= hogs.ar^[GetRandom(hogs.size)]^.Hedgehog
+ else if hogs.size = 1 then Gear^.Hedgehog:= hogs.ar^[0]^.Hedgehog
+ else Gear^.Hedgehog:= nil;
+ if Gear^.Hedgehog <> nil then Gear^.Timer:= 5000;
+ exit
+ end;
+
+// we have a target. move the creeper.
+if HHGear <> nil then
+ begin
+ // GOTCHA
+ if ((abs(HHGear^.X.Round-Gear^.X.Round) + abs(HHGear^.Y.Round-Gear^.Y.Round) + 2) < 50) and
+ (Distance(HHGear^.X-Gear^.X,HHGear^.Y-Gear^.Y) < _50) then
+ begin
+ // hisssssssssss
+ Gear^.State:= Gear^.State or gstTmpFlag;
+ Gear^.Timer:= 1500;
+ exit
+ end;
+ if (Gear^.State and gstMoving <> 0) then
+ begin
+ Gear^.dY:= _0;
+ Gear^.dX:= _0;
+ end
+ else if (GameTicks and $FF = 0) then
+ begin
+ tdX:= HHGear^.X-Gear^.X;
+ dir:= hwSign(tdX);
+ if not TestCollisionX(Gear, dir) then
+ Gear^.X:= Gear^.X + signAs(_1,tdX);
+ if TestCollisionXwithXYShift(Gear, signAs(_10,tdX), 0, dir) then
+ begin
+ Gear^.dX:= SignAs(_0_15, tdX);
+ Gear^.dY:= -_0_3;
+ Gear^.State:= Gear^.State or gstMoving
+ end
+ end;
+ end;
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepKnife(Gear: PGear);
+//var ox, oy: LongInt;
+// la: hwFloat;
+var a: real;
+begin
+ // Gear is shrunk so it can actually escape the hog without carving into the terrain
+ if (Gear^.Radius = 4) and (Gear^.CollisionMask = $FFFF) then Gear^.Radius:= 7;
+ if Gear^.Damage > 100 then Gear^.CollisionMask:= 0
+ else if Gear^.Damage > 30 then
+ if GetRandom(max(4,18-Gear^.Damage div 10)) < 3 then Gear^.CollisionMask:= 0;
+ Gear^.Damage:= 0;
+ if Gear^.Timer > 0 then dec(Gear^.Timer);
+ if (Gear^.State and gstMoving <> 0) and (Gear^.State and gstCollision = 0) then
+ begin
+ DeleteCI(Gear);
+ Gear^.Radius:= 7;
+ // used for damage and impact calc. needs balancing I think
+ Gear^.Health:= hwRound(hwSqr((hwAbs(Gear^.dY)+hwAbs(Gear^.dX))*_4));
+ doStepFallingGear(Gear);
+ AllInactive := false;
+ a:= Gear^.DirAngle;
+ CalcRotationDirAngle(Gear);
+ Gear^.DirAngle:= a+(Gear^.DirAngle-a)*2*hwSign(Gear^.dX) // double rotation
+ end
+ else if (Gear^.CollisionIndex = -1) and (Gear^.Timer = 0) then
+ begin
+ (*ox:= 0; oy:= 0;
+ if TestCollisionYwithGear(Gear, -1) <> 0 then oy:= -1;
+ if TestCollisionXwithGear(Gear, 1) then ox:= 1;
+ if TestCollisionXwithGear(Gear, -1) then ox:= -1;
+ if TestCollisionYwithGear(Gear, 1) <> 0 then oy:= 1;
+ if Gear^.Health > 0 then
+ PlaySound(sndRopeAttach);
+
+ la:= _10000;
+ if (ox <> 0) or (oy <> 0) then
+ la:= CalcSlopeNearGear(Gear, ox, oy);
+ if la = _10000 then
+ begin
+ // debug for when we couldn't get an angle
+ //AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeWhite);
+*)
+ Gear^.DirAngle:= DxDy2Angle(Gear^.dX, Gear^.dY) + (random(30)-15);
+ if (Gear^.dX.isNegative and Gear^.dY.isNegative) or
+ ((not Gear^.dX.isNegative) and (not Gear^.dY.isNegative)) then Gear^.DirAngle:= Gear^.DirAngle-90;
+ // end
+ // else Gear^.DirAngle:= hwFloat2Float(la)*90; // sheepluva's comment claims 45deg = 0.5 - yet orientation doesn't seem consistent?
+ // AddFileLog('la: '+floattostr(la)+' DirAngle: '+inttostr(round(Gear^.DirAngle)));
+ Gear^.dX:= _0;
+ Gear^.dY:= _0;
+ Gear^.State:= Gear^.State and (not gstMoving) or gstCollision;
+ Gear^.Radius:= 16;
+ if Gear^.Health > 0 then AmmoShove(Gear, Gear^.Health, 0);
+ Gear^.Health:= 0;
+ Gear^.Timer:= 500;
+ AddCI(Gear)
+ end
+ else if GameTicks and $3F = 0 then
+ begin
+ if (TestCollisionYwithGear(Gear, -1) = 0)
+ and (not TestCollisionXwithGear(Gear, 1))
+ and (not TestCollisionXwithGear(Gear, -1))
+ and (TestCollisionYwithGear(Gear, 1) = 0) then Gear^.State:= Gear^.State and (not gstCollision) or gstMoving;
+ end
+end;
+(*
+ This didn't end up getting used, but, who knows, might be reasonable for javellin or something
+// Make the knife initial angle based on the hog attack angle, or is that too hard?
+procedure doStepKnife(Gear: PGear);
+var t,
+ gx, gy, ga, // gear x,y,angle
+ lx, ly, la, // land x,y,angle
+ ox, oy, // x,y offset
+ w, h, // wXh of clip area
+ tx, ty // tip position in sprite
+ : LongInt;
+ surf: PSDL_Surface;
+ s: hwFloat;
+
+begin
+ Gear^.dY := Gear^.dY + cGravity;
+ if (GameFlags and gfMoreWind) <> 0 then
+ Gear^.dX := Gear^.dX + cWindSpeed / Gear^.Density;
+ Gear^.X := Gear^.X + Gear^.dX;
+ Gear^.Y := Gear^.Y + Gear^.dY;
+ CheckGearDrowning(Gear);
+ gx:= hwRound(Gear^.X);
+ gy:= hwRound(Gear^.Y);
+ if Gear^.State and gstDrowning <> 0 then exit;
+ with Gear^ do
+ begin
+ if CheckLandValue(gx, gy, lfLandMask) then
+ begin
+ t:= Angle + hwRound((hwAbs(dX)+hwAbs(dY)) * _10);
+
+ if t < 0 then inc(t, 4096)
+ else if 4095 < t then dec(t, 4096);
+ Angle:= t;
+
+ DirAngle:= Angle / 4096 * 360
+ end
+ else
+ begin
+//This is the set of postions for the knife.
+//Using FlipSurface and copyToXY the knife can be written to the LandPixels at 32 positions, and an appropriate line drawn in Land.
+ t:= Angle mod 1024;
+ case t div 128 of
+ 0: begin
+ ox:= 2; oy:= 5;
+ w := 25; h:= 5;
+ tx:= 0; ty:= 2
+ end;
+ 1: begin
+ ox:= 2; oy:= 15;
+ w:= 24; h:= 8;
+ tx:= 0; ty:= 7
+ end;
+ 2: begin
+ ox:= 2; oy:= 27;
+ w:= 23; h:= 12;
+ tx:= -12; ty:= -5
+ end;
+ 3: begin
+ ox:= 2; oy:= 43;
+ w:= 21; h:= 15;
+ tx:= 0; ty:= 14
+ end;
+ 4: begin
+ ox:= 29; oy:= 8;
+ w:= 19; h:= 19;
+ tx:= 0; ty:= 17
+ end;
+ 5: begin
+ ox:= 29; oy:= 32;
+ w:= 15; h:= 21;
+ tx:= 0; ty:= 20
+ end;
+ 6: begin
+ ox:= 51; oy:= 3;
+ w:= 11; h:= 23;
+ tx:= 0; ty:= 22
+ end;
+ 7: begin
+ ox:= 51; oy:= 34;
+ w:= 7; h:= 24;
+ tx:= 0; ty:= 23
+ end
+ end;
+
+ surf:= SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, RMask, GMask, BMask, AMask);
+ copyToXYFromRect(SpritesData[sprKnife].Surface, surf, ox, oy, w, h, 0, 0);
+ // try to make the knife hit point first
+ lx := 0;
+ ly := 0;
+ if CalcSlopeTangent(Gear, gx, gy, lx, ly, 255) then
+ begin
+ la:= vector2Angle(int2hwFloat(lx), int2hwFloat(ly));
+ ga:= vector2Angle(dX, dY);
+ AddFileLog('la: '+inttostr(la)+' ga: '+inttostr(ga)+' Angle: '+inttostr(Angle));
+ // change to 0 to 4096 forced by LongWord in Gear
+ if la < 0 then la:= 4096+la;
+ if ga < 0 then ga:= 4096+ga;
+ if ((Angle > ga) and (Angle < la)) or ((Angle < ga) and (Angle > la)) then
+ begin
+ if Angle >= 2048 then dec(Angle, 2048)
+ else if Angle < 2048 then inc(Angle, 2048)
+ end;
+ AddFileLog('la: '+inttostr(la)+' ga: '+inttostr(ga)+' Angle: '+inttostr(Angle))
+ end;
+ case Angle div 1024 of
+ 0: begin
+ flipSurface(surf, true);
+ flipSurface(surf, true);
+ BlitImageAndGenerateCollisionInfo(gx-(w-tx), gy-(h-ty), w, surf)
+ end;
+ 1: begin
+ flipSurface(surf, false);
+ BlitImageAndGenerateCollisionInfo(gx-(w-tx), gy-ty, w, surf)
+ end;
+ 2: begin // knife was actually drawn facing this way...
+ BlitImageAndGenerateCollisionInfo(gx-tx, gy-ty, w, surf)
+ end;
+ 3: begin
+ flipSurface(surf, true);
+ BlitImageAndGenerateCollisionInfo(gx-tx, gy-(h-ty), w, surf)
+ end
+ end;
+ SDL_FreeSurface(surf);
+ // this needs to calculate actual width/height + land clipping since update texture doesn't.
+ // i.e. this will crash if you fire near sides of map, but until I get the blit right, not going to put real values
+ UpdateLandTexture(hwRound(X)-32, 64, hwRound(Y)-32, 64, true);
+ DeleteGear(Gear);
+ exit
+ end
+ end;
+end;
+*)
+
+end.
--- a/hedgewars/uGearsHedgehog.pas Mon Jul 01 22:28:42 2013 +0300
+++ b/hedgewars/uGearsHedgehog.pas Mon Jul 01 23:23:22 2013 +0300
@@ -33,9 +33,9 @@
implementation
uses uConsts, uVariables, uFloat, uAmmos, uSound, uCaptions,
- uCommands, uLocale, uUtils, uVisualGears, uStats, uIO, uScript,
- uGearsList, uGears, uCollisions, uRandom, uStore, uTeams,
- uGearsUtils;
+ uCommands, uLocale, uUtils, uStats, uIO, uScript,
+ uGearsList, uCollisions, uRandom, uStore, uTeams,
+ uGearsUtils, uVisualGearsList;
var GHStepTicks: LongWord = 0;
@@ -800,7 +800,7 @@
MakeHedgehogsStep(Gear);
SetAllHHToActive(false);
- AddGearCI(Gear)
+ AddCI(Gear)
end
end;
@@ -1145,7 +1145,7 @@
if ((HHGear^.State and (gstMoving or gstDrowning)) = 0) then
begin
- AddGearCI(HHGear);
+ AddCI(HHGear);
if wasJumping then
GHStepTicks:= 410
else
@@ -1227,7 +1227,7 @@
begin
Gear^.State:= Gear^.State and (not (gstWait or gstLoser or gstWinner or gstAttacked or gstNotKickable or gstHHChooseTarget));
if Gear^.Hedgehog^.Effects[heFrozen] = 0 then Gear^.Active:= false;
- AddGearCI(Gear);
+ AddCI(Gear);
exit
end
else dec(Gear^.Timer)
--- a/hedgewars/uGearsRender.pas Mon Jul 01 22:28:42 2013 +0300
+++ b/hedgewars/uGearsRender.pas Mon Jul 01 23:23:22 2013 +0300
@@ -38,7 +38,7 @@
end;
implementation
-uses uRender, uUtils, uVariables, uAmmos, Math, uVisualGears;
+uses uRender, uUtils, uVariables, uAmmos, Math, uVisualGearsList;
procedure DrawRopeLinesRQ(Gear: PGear);
begin
--- a/hedgewars/uGearsUtils.pas Mon Jul 01 22:28:42 2013 +0300
+++ b/hedgewars/uGearsUtils.pas Mon Jul 01 23:23:22 2013 +0300
@@ -20,7 +20,7 @@
unit uGearsUtils;
interface
-uses uTypes;
+uses uTypes, uFloat;
procedure doMakeExplosion(X, Y, Radius: LongInt; AttackingHog: PHedgehog; Mask: Longword); inline;
procedure doMakeExplosion(X, Y, Radius: LongInt; AttackingHog: PHedgehog; Mask: Longword; const Tint: LongWord);
@@ -41,16 +41,31 @@
procedure CheckCollision(Gear: PGear); inline;
procedure CheckCollisionWithLand(Gear: PGear); inline;
+procedure AmmoShove(Ammo: PGear; Damage, Power: LongInt);
+function GearsNear(X, Y: hwFloat; Kind: TGearType; r: LongInt): PGearArrayS;
+procedure SpawnBoxOfSmth;
+procedure ShotgunShot(Gear: PGear);
+
+procedure SetAllToActive;
+procedure SetAllHHToActive; inline;
+procedure SetAllHHToActive(Ice: boolean);
+
+function GetAmmo(Hedgehog: PHedgehog): TAmmoType;
+function GetUtility(Hedgehog: PHedgehog): TAmmoType;
+
+
+
function MakeHedgehogsStep(Gear: PGear) : boolean;
var doStepHandlers: array[TGearType] of TGearStepProcedure;
implementation
-uses uFloat, uSound, uCollisions, uUtils, uConsts, uVisualGears, uAIMisc,
+uses uSound, uCollisions, uUtils, uConsts, uVisualGears, uAIMisc,
uVariables, uLandGraphics, uScript, uStats, uCaptions, uTeams, uStore,
- uLocale, uTextures, uRenderUtils, uRandom, SDLh, uDebug, uGears,
- uGearsList, Math;
+ uLocale, uTextures, uRenderUtils, uRandom, SDLh, uDebug,
+ uGearsList, Math, uVisualGearsList, uGearsHandlersMess,
+ uGearsHedgehog;
procedure doMakeExplosion(X, Y, Radius: LongInt; AttackingHog: PHedgehog; Mask: Longword); inline;
begin
@@ -766,4 +781,422 @@
end;
end;
+
+procedure ShotgunShot(Gear: PGear);
+var t: PGear;
+ dmg, r, dist: LongInt;
+ dx, dy: hwFloat;
+begin
+Gear^.Radius:= cShotgunRadius;
+t:= GearsList;
+while t <> nil do
+ begin
+ case t^.Kind of
+ gtHedgehog,
+ gtMine,
+ gtSMine,
+ gtKnife,
+ gtCase,
+ gtTarget,
+ gtExplosives: begin//,
+// gtStructure: begin
+//addFileLog('ShotgunShot radius: ' + inttostr(Gear^.Radius) + ', t^.Radius = ' + inttostr(t^.Radius) + ', distance = ' + inttostr(dist) + ', dmg = ' + inttostr(dmg));
+ dmg:= 0;
+ r:= Gear^.Radius + t^.Radius;
+ dx:= Gear^.X-t^.X;
+ dx.isNegative:= false;
+ dy:= Gear^.Y-t^.Y;
+ dy.isNegative:= false;
+ if r-hwRound(dx+dy) > 0 then
+ begin
+ dist:= hwRound(Distance(dx, dy));
+ dmg:= ModifyDamage(min(r - dist, 25), t);
+ end;
+ if dmg > 0 then
+ begin
+ if (not t^.Invulnerable) then
+ ApplyDamage(t, Gear^.Hedgehog, dmg, dsBullet)
+ else
+ Gear^.State:= Gear^.State or gstWinner;
+
+ DeleteCI(t);
+ t^.dX:= t^.dX + Gear^.dX * dmg * _0_01 + SignAs(cHHKick, Gear^.dX);
+ t^.dY:= t^.dY + Gear^.dY * dmg * _0_01;
+ t^.State:= t^.State or gstMoving;
+ if t^.Kind = gtKnife then t^.State:= t^.State and (not gstCollision);
+ t^.Active:= true;
+ FollowGear:= t
+ end
+ end;
+ gtGrave: begin
+ dmg:= 0;
+ r:= Gear^.Radius + t^.Radius;
+ dx:= Gear^.X-t^.X;
+ dx.isNegative:= false;
+ dy:= Gear^.Y-t^.Y;
+ dy.isNegative:= false;
+ if r-hwRound(dx+dy) > 0 then
+ begin
+ dist:= hwRound(Distance(dx, dy));
+ dmg:= ModifyDamage(min(r - dist, 25), t);
+ end;
+ if dmg > 0 then
+ begin
+ t^.dY:= - _0_1;
+ t^.Active:= true
+ end
+ end;
+ end;
+ t:= t^.NextGear
+ end;
+if (GameFlags and gfSolidLand) = 0 then
+ DrawExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), cShotgunRadius)
+end;
+
+procedure AmmoShove(Ammo: PGear; Damage, Power: LongInt);
+var t: PGearArray;
+ Gear: PGear;
+ i, j, tmpDmg: LongInt;
+ VGear: PVisualGear;
+begin
+t:= CheckGearsCollision(Ammo);
+// Just to avoid hogs on rope dodging fire.
+if (CurAmmoGear <> nil) and ((CurAmmoGear^.Kind = gtRope) or (CurAmmoGear^.Kind = gtJetpack) or (CurAmmoGear^.Kind = gtBirdy))
+and (CurrentHedgehog^.Gear <> nil) and (CurrentHedgehog^.Gear^.CollisionIndex = -1)
+and (sqr(hwRound(Ammo^.X) - hwRound(CurrentHedgehog^.Gear^.X)) + sqr(hwRound(Ammo^.Y) - hwRound(CurrentHedgehog^.Gear^.Y)) <= sqr(cHHRadius + Ammo^.Radius)) then
+ begin
+ t^.ar[t^.Count]:= CurrentHedgehog^.Gear;
+ inc(t^.Count)
+ end;
+
+i:= t^.Count;
+
+if (Ammo^.Kind = gtFlame) and (i > 0) then
+ Ammo^.Health:= 0;
+while i > 0 do
+ begin
+ dec(i);
+ Gear:= t^.ar[i];
+ if ((Ammo^.Kind = gtFlame) or (Ammo^.Kind = gtBlowTorch)) and
+ (Gear^.Kind = gtHedgehog) and (Gear^.Hedgehog^.Effects[heFrozen] > 255) then
+ Gear^.Hedgehog^.Effects[heFrozen]:= max(255,Gear^.Hedgehog^.Effects[heFrozen]-10000);
+ tmpDmg:= ModifyDamage(Damage, Gear);
+ if (Gear^.State and gstNoDamage) = 0 then
+ begin
+
+ if (Ammo^.Kind = gtDEagleShot) or (Ammo^.Kind = gtSniperRifleShot) then
+ begin
+ VGear := AddVisualGear(hwround(Ammo^.X), hwround(Ammo^.Y), vgtBulletHit);
+ if VGear <> nil then
+ VGear^.Angle := DxDy2Angle(-Ammo^.dX, Ammo^.dY);
+ end;
+
+ if (Gear^.Kind = gtHedgehog) and (Ammo^.State and gsttmpFlag <> 0) and (Ammo^.Kind = gtShover) then
+ Gear^.FlightTime:= 1;
+
+
+ case Gear^.Kind of
+ gtHedgehog,
+ gtMine,
+ gtSMine,
+ gtKnife,
+ gtTarget,
+ gtCase,
+ gtExplosives: //,
+ //gtStructure:
+ begin
+ if (Ammo^.Kind = gtDrill) then
+ begin
+ Ammo^.Timer:= 0;
+ exit;
+ end;
+ if (not Gear^.Invulnerable) then
+ begin
+ if (Ammo^.Kind = gtKnife) and (tmpDmg > 0) then
+ for j:= 1 to max(1,min(3,tmpDmg div 5)) do
+ begin
+ VGear:= AddVisualGear(hwRound(Ammo^.X-((Ammo^.X-Gear^.X)/_2)), hwRound(Ammo^.Y-((Ammo^.Y-Gear^.Y)/_2)), vgtStraightShot);
+ if VGear <> nil then
+ with VGear^ do
+ begin
+ Tint:= $FFCC00FF;
+ Angle:= random(360);
+ dx:= 0.0005 * (random(100));
+ dy:= 0.0005 * (random(100));
+ if random(2) = 0 then
+ dx := -dx;
+ if random(2) = 0 then
+ dy := -dy;
+ FrameTicks:= 600+random(200);
+ State:= ord(sprStar)
+ end
+ end;
+ ApplyDamage(Gear, Ammo^.Hedgehog, tmpDmg, dsShove)
+ end
+ else
+ Gear^.State:= Gear^.State or gstWinner;
+ if (Gear^.Kind = gtExplosives) and (Ammo^.Kind = gtBlowtorch) then
+ begin
+ if (Ammo^.Hedgehog^.Gear <> nil) then
+ Ammo^.Hedgehog^.Gear^.State:= Ammo^.Hedgehog^.Gear^.State and (not gstNotKickable);
+ ApplyDamage(Gear, Ammo^.Hedgehog, tmpDmg * 100, dsUnknown); // crank up damage for explosives + blowtorch
+ end;
+
+ if (Gear^.Kind = gtHedgehog) and (Gear^.Hedgehog^.King or (Gear^.Hedgehog^.Effects[heFrozen] > 0)) then
+ begin
+ Gear^.dX:= Ammo^.dX * Power * _0_005;
+ Gear^.dY:= Ammo^.dY * Power * _0_005
+ end
+ else if ((Ammo^.Kind <> gtFlame) or (Gear^.Kind = gtHedgehog)) and (Power <> 0) then
+ begin
+ Gear^.dX:= Ammo^.dX * Power * _0_01;
+ Gear^.dY:= Ammo^.dY * Power * _0_01
+ end;
+
+ if (not isZero(Gear^.dX)) or (not isZero(Gear^.dY)) then
+ begin
+ Gear^.Active:= true;
+ DeleteCI(Gear);
+ Gear^.State:= Gear^.State or gstMoving;
+ if Gear^.Kind = gtKnife then Gear^.State:= Gear^.State and (not gstCollision);
+ // move the gear upwards a bit to throw it over tiny obstacles at start
+ if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then
+ begin
+ if not (TestCollisionXwithXYShift(Gear, _0, -3, hwSign(Gear^.dX))
+ or (TestCollisionYwithGear(Gear, -1) <> 0)) then
+ Gear^.Y:= Gear^.Y - _1;
+ if not (TestCollisionXwithXYShift(Gear, _0, -2, hwSign(Gear^.dX))
+ or (TestCollisionYwithGear(Gear, -1) <> 0)) then
+ Gear^.Y:= Gear^.Y - _1;
+ if not (TestCollisionXwithXYShift(Gear, _0, -1, hwSign(Gear^.dX))
+ or (TestCollisionYwithGear(Gear, -1) <> 0)) then
+ Gear^.Y:= Gear^.Y - _1;
+ end
+ end;
+
+
+ if (Ammo^.Kind <> gtFlame) or ((Ammo^.State and gsttmpFlag) = 0) then
+ FollowGear:= Gear
+ end;
+ end
+ end;
+ end;
+if i <> 0 then
+ SetAllToActive
+end;
+
+
+function CountGears(Kind: TGearType): Longword;
+var t: PGear;
+ count: Longword = 0;
+begin
+
+t:= GearsList;
+while t <> nil do
+ begin
+ if t^.Kind = Kind then
+ inc(count);
+ t:= t^.NextGear
+ end;
+CountGears:= count;
+end;
+
+procedure SetAllToActive;
+var t: PGear;
+begin
+AllInactive:= false;
+t:= GearsList;
+while t <> nil do
+ begin
+ t^.Active:= true;
+ t:= t^.NextGear
+ end
+end;
+
+procedure SetAllHHToActive; inline;
+begin
+SetAllHHToActive(true)
+end;
+
+
+procedure SetAllHHToActive(Ice: boolean);
+var t: PGear;
+begin
+AllInactive:= false;
+t:= GearsList;
+while t <> nil do
+ begin
+ if (t^.Kind = gtHedgehog) or (t^.Kind = gtExplosives) then
+ begin
+ if (t^.Kind = gtHedgehog) and Ice then CheckIce(t);
+ t^.Active:= true
+ end;
+ t:= t^.NextGear
+ end
+end;
+
+
+var GearsNearArray : TPGearArray;
+function GearsNear(X, Y: hwFloat; Kind: TGearType; r: LongInt): PGearArrayS;
+var
+ t: PGear;
+ s: Longword;
+begin
+ r:= r*r;
+ s:= 0;
+ SetLength(GearsNearArray, s);
+ t := GearsList;
+ while t <> nil do
+ begin
+ if (t^.Kind = Kind)
+ and ((X - t^.X)*(X - t^.X) + (Y - t^.Y)*(Y-t^.Y) < int2hwFloat(r)) then
+ begin
+ inc(s);
+ SetLength(GearsNearArray, s);
+ GearsNearArray[s - 1] := t;
+ end;
+ t := t^.NextGear;
+ end;
+
+ GearsNear.size:= s;
+ GearsNear.ar:= @GearsNearArray
+end;
+
+
+procedure SpawnBoxOfSmth;
+var t, aTot, uTot, a, h: LongInt;
+ i: TAmmoType;
+begin
+if (PlacingHogs) or
+ (cCaseFactor = 0)
+ or (CountGears(gtCase) >= 5)
+ or (GetRandom(cCaseFactor) <> 0) then
+ exit;
+
+FollowGear:= nil;
+aTot:= 0;
+uTot:= 0;
+for i:= Low(TAmmoType) to High(TAmmoType) do
+ if (Ammoz[i].Ammo.Propz and ammoprop_Utility) = 0 then
+ inc(aTot, Ammoz[i].Probability)
+ else
+ inc(uTot, Ammoz[i].Probability);
+
+t:=0;
+a:=aTot;
+h:= 1;
+
+if (aTot+uTot) <> 0 then
+ if ((GameFlags and gfInvulnerable) = 0) then
+ begin
+ h:= cHealthCaseProb * 100;
+ t:= GetRandom(10000);
+ a:= (10000-h)*aTot div (aTot+uTot)
+ end
+ else
+ begin
+ t:= GetRandom(aTot+uTot);
+ h:= 0
+ end;
+
+
+if t<h then
+ begin
+ FollowGear:= AddGear(0, 0, gtCase, 0, _0, _0, 0);
+ FollowGear^.Health:= cHealthCaseAmount;
+ FollowGear^.Pos:= posCaseHealth;
+ AddCaption(GetEventString(eidNewHealthPack), cWhiteColor, capgrpAmmoInfo);
+ end
+else if (t<a+h) then
+ begin
+ t:= aTot;
+ if (t > 0) then
+ begin
+ FollowGear:= AddGear(0, 0, gtCase, 0, _0, _0, 0);
+ t:= GetRandom(t);
+ i:= Low(TAmmoType);
+ FollowGear^.Pos:= posCaseAmmo;
+ FollowGear^.AmmoType:= i;
+ AddCaption(GetEventString(eidNewAmmoPack), cWhiteColor, capgrpAmmoInfo);
+ end
+ end
+else
+ begin
+ t:= uTot;
+ if (t > 0) then
+ begin
+ FollowGear:= AddGear(0, 0, gtCase, 0, _0, _0, 0);
+ t:= GetRandom(t);
+ i:= Low(TAmmoType);
+ FollowGear^.Pos:= posCaseUtility;
+ FollowGear^.AmmoType:= i;
+ AddCaption(GetEventString(eidNewUtilityPack), cWhiteColor, capgrpAmmoInfo);
+ end
+ end;
+
+// handles case of no ammo or utility crates - considered also placing booleans in uAmmos and altering probabilities
+if (FollowGear <> nil) then
+ begin
+ FindPlace(FollowGear, true, 0, LAND_WIDTH);
+
+ if (FollowGear <> nil) then
+ AddVoice(sndReinforce, CurrentTeam^.voicepack)
+ end
+end;
+
+
+function GetAmmo(Hedgehog: PHedgehog): TAmmoType;
+var t, aTot: LongInt;
+ i: TAmmoType;
+begin
+Hedgehog:= Hedgehog; // avoid hint
+
+aTot:= 0;
+for i:= Low(TAmmoType) to High(TAmmoType) do
+ if (Ammoz[i].Ammo.Propz and ammoprop_Utility) = 0 then
+ inc(aTot, Ammoz[i].Probability);
+
+t:= aTot;
+i:= Low(TAmmoType);
+if (t > 0) then
+ begin
+ t:= GetRandom(t);
+ while t >= 0 do
+ begin
+ inc(i);
+ if (Ammoz[i].Ammo.Propz and ammoprop_Utility) = 0 then
+ dec(t, Ammoz[i].Probability)
+ end
+ end;
+GetAmmo:= i
+end;
+
+function GetUtility(Hedgehog: PHedgehog): TAmmoType;
+var t, uTot: LongInt;
+ i: TAmmoType;
+begin
+
+uTot:= 0;
+for i:= Low(TAmmoType) to High(TAmmoType) do
+ if ((Ammoz[i].Ammo.Propz and ammoprop_Utility) <> 0)
+ and ((Hedgehog^.Team^.HedgehogsNumber > 1) or (Ammoz[i].Ammo.AmmoType <> amSwitch)) then
+ inc(uTot, Ammoz[i].Probability);
+
+t:= uTot;
+i:= Low(TAmmoType);
+if (t > 0) then
+ begin
+ t:= GetRandom(t);
+ while t >= 0 do
+ begin
+ inc(i);
+ if ((Ammoz[i].Ammo.Propz and ammoprop_Utility) <> 0) and ((Hedgehog^.Team^.HedgehogsNumber > 1)
+ or (Ammoz[i].Ammo.AmmoType <> amSwitch)) then
+ dec(t, Ammoz[i].Probability)
+ end
+ end;
+GetUtility:= i
+end;
+
+
end.
--- a/hedgewars/uIO.pas Mon Jul 01 22:28:42 2013 +0300
+++ b/hedgewars/uIO.pas Mon Jul 01 23:23:22 2013 +0300
@@ -411,6 +411,9 @@
procedure chFatalError(var s: shortstring);
begin
SendIPC('E' + s);
+ // TODO: should we try to clean more stuff here?
+ SDL_Quit;
+ halt(2)
end;
procedure doPut(putX, putY: LongInt; fromAI: boolean);
--- a/hedgewars/uLand.pas Mon Jul 01 22:28:42 2013 +0300
+++ b/hedgewars/uLand.pas Mon Jul 01 23:23:22 2013 +0300
@@ -20,7 +20,7 @@
unit uLand;
interface
-uses SDLh, uLandTemplates, uFloat, uConsts, GLunit, uTypes, uAILandMarks;
+uses SDLh, uLandTemplates, uFloat, uConsts, uTypes, uAILandMarks;
procedure initModule;
procedure freeModule;
--- a/hedgewars/uLandObjects.pas Mon Jul 01 22:28:42 2013 +0300
+++ b/hedgewars/uLandObjects.pas Mon Jul 01 23:23:22 2013 +0300
@@ -32,7 +32,7 @@
procedure SetLand(var LandWord: Word; Pixel: LongWord); inline;
implementation
-uses uStore, uConsts, uConsole, uRandom, uSound, GLunit
+uses uStore, uConsts, uConsole, uRandom, uSound
, uTypes, uVariables, uUtils, uDebug, SysUtils
, uPhysFSLayer;
@@ -535,7 +535,7 @@
SkyColor.g:= t;
SkyColor.b:= t
end;
- glClearColor(SkyColor.r / 255, SkyColor.g / 255, SkyColor.b / 255, 0.99);
+ SetSkyColor(SkyColor.r / 255, SkyColor.g / 255, SkyColor.b / 255);
SDSkyColor.r:= SkyColor.r;
SDSkyColor.g:= SkyColor.g;
SDSkyColor.b:= SkyColor.b;
@@ -794,7 +794,7 @@
RQSkyColor.g:= t;
RQSkyColor.b:= t
end;
- glClearColor(RQSkyColor.r / 255, RQSkyColor.g / 255, RQSkyColor.b / 255, 0.99);
+ SetSkyColor(RQSkyColor.r / 255, RQSkyColor.g / 255, RQSkyColor.b / 255);
SDSkyColor.r:= RQSkyColor.r;
SDSkyColor.g:= RQSkyColor.g;
SDSkyColor.b:= RQSkyColor.b;
--- a/hedgewars/uScript.pas Mon Jul 01 22:28:42 2013 +0300
+++ b/hedgewars/uScript.pas Mon Jul 01 23:23:22 2013 +0300
@@ -58,7 +58,6 @@
uses LuaPas,
uConsole,
uConsts,
- uVisualGears,
uGears,
uGearsList,
uGearsUtils,
@@ -84,6 +83,8 @@
SDLh,
SysUtils,
uIO,
+ uVisualGearsList,
+ uGearsHandlersMess,
uPhysFSLayer,
typinfo
;
@@ -1488,7 +1489,7 @@
gear^.X:= int2hwfloat(x);
gear^.Y:= int2hwfloat(y);
if col then
- AddGearCI(gear);
+ AddCI(gear);
SetAllToActive
end
end;
--- a/hedgewars/uStore.pas Mon Jul 01 22:28:42 2013 +0300
+++ b/hedgewars/uStore.pas Mon Jul 01 23:23:22 2013 +0300
@@ -54,6 +54,7 @@
procedure WarpMouse(x, y: Word); inline;
procedure SwapBuffers; {$IFDEF USE_VIDEO_RECORDING}cdecl{$ELSE}inline{$ENDIF};
+procedure SetSkyColor(r, g, b: real);
implementation
uses uMisc, uConsole, uVariables, uUtils, uTextures, uRender, uRenderUtils, uCommands
@@ -1258,11 +1259,11 @@
// clean the window from any previous content
glClear(GL_COLOR_BUFFER_BIT);
if SuddenDeathDmg then
- glClearColor(SDSkyColor.r * (SDTint/255) / 255, SDSkyColor.g * (SDTint/255) / 255, SDSkyColor.b * (SDTint/255) / 255, 0.99)
+ SetSkyColor(SDSkyColor.r * (SDTint/255) / 255, SDSkyColor.g * (SDTint/255) / 255, SDSkyColor.b * (SDTint/255) / 255)
else if ((cReducedQuality and rqNoBackground) = 0) then
- glClearColor(SkyColor.r / 255, SkyColor.g / 255, SkyColor.b / 255, 0.99)
+ SetSkyColor(SkyColor.r / 255, SkyColor.g / 255, SkyColor.b / 255)
else
- glClearColor(RQSkyColor.r / 255, RQSkyColor.g / 255, RQSkyColor.b / 255, 0.99);
+ SetSkyColor(RQSkyColor.r / 255, RQSkyColor.g / 255, RQSkyColor.b / 255);
// reload everything we had before
ReloadCaptions(false);
@@ -1273,6 +1274,31 @@
end;
end;
+procedure WarpMouse(x, y: Word); inline;
+begin
+{$IFDEF SDL13}
+ SDL_WarpMouseInWindow(SDLwindow, x, y);
+{$ELSE}
+ x:= x; y:= y; // avoid hints
+{$ENDIF}
+end;
+
+procedure SwapBuffers; {$IFDEF USE_VIDEO_RECORDING}cdecl{$ELSE}inline{$ENDIF};
+begin
+ if GameType = gmtRecord then
+ exit;
+{$IFDEF SDL13}
+ SDL_GL_SwapWindow(SDLwindow);
+{$ELSE}
+ SDL_GL_SwapBuffers();
+{$ENDIF}
+end;
+
+procedure SetSkyColor(r, g, b: real);
+begin
+ glClearColor(r, g, b, 0.99)
+end;
+
procedure initModule;
var ai: TAmmoType;
i: LongInt;
@@ -1310,25 +1336,4 @@
{$ENDIF}
SDL_Quit();
end;
-
-procedure WarpMouse(x, y: Word); inline;
-begin
-{$IFDEF SDL13}
- SDL_WarpMouseInWindow(SDLwindow, x, y);
-{$ELSE}
- x:= x; y:= y; // avoid hints
-{$ENDIF}
-end;
-
-procedure SwapBuffers; {$IFDEF USE_VIDEO_RECORDING}cdecl{$ELSE}inline{$ENDIF};
-begin
- if GameType = gmtRecord then
- exit;
-{$IFDEF SDL13}
- SDL_GL_SwapWindow(SDLwindow);
-{$ELSE}
- SDL_GL_SwapBuffers();
-{$ENDIF}
-end;
-
end.
--- a/hedgewars/uTeams.pas Mon Jul 01 22:28:42 2013 +0300
+++ b/hedgewars/uTeams.pas Mon Jul 01 23:23:22 2013 +0300
@@ -1,4 +1,4 @@
-(*
+ (*
* Hedgewars, a free turn based strategy game
* Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr@gmail.com>
*
@@ -20,8 +20,8 @@
unit uTeams;
interface
-uses uConsts, uInputHandler, uRandom, uFloat, uStats, uVisualGears,
- uCollisions, GLunit, uSound, uStore, uTypes, uScript
+uses uConsts, uInputHandler, uRandom, uFloat, uStats,
+ uCollisions, uSound, uStore, uTypes, uScript
{$IFDEF USE_TOUCH_INTERFACE}, uWorld{$ENDIF};
@@ -43,7 +43,7 @@
implementation
uses uLocale, uAmmos, uChat, uVariables, uUtils, uIO, uCaptions, uCommands, uDebug,
- uGearsUtils, uGearsList
+ uGearsUtils, uGearsList, uVisualGearsList
{$IFDEF USE_TOUCH_INTERFACE}, uTouch{$ENDIF};
var MaxTeamHealth: LongInt;
@@ -126,7 +126,7 @@
DeleteCI(Gear);
FindPlace(Gear, false, 0, LAND_WIDTH);
if Gear <> nil then
- AddGearCI(Gear)
+ AddCI(Gear)
end
end;
@@ -504,7 +504,7 @@
HH^.GearHidden:= nil;
InsertGearToList(HH^.Gear);
HH^.Gear^.State:= (HH^.Gear^.State and (not (gstHHDriven or gstInvisible or gstAttacking))) or gstAttacked;
- AddGearCI(HH^.Gear);
+ AddCI(HH^.Gear);
HH^.Gear^.Active:= true;
ScriptCall('onHogRestore', HH^.Gear^.Uid)
end;
@@ -688,8 +688,8 @@
CurrentHedgehog:= newHog;
if (CurrentHedgehog <> nil) and (CurrentHedgehog^.CurAmmoType = amKnife) then
LoadHedgehogHat(CurrentHedgehog^, 'Reserved/chef');
- if oldCI then AddGearCI(oldHH^.Gear);
- if newCI then AddGearCI(newHog^.Gear)
+ if oldCI then AddCI(oldHH^.Gear);
+ if newCI then AddCI(newHog^.Gear)
end;
--- a/hedgewars/uUtils.pas Mon Jul 01 22:28:42 2013 +0300
+++ b/hedgewars/uUtils.pas Mon Jul 01 23:23:22 2013 +0300
@@ -21,7 +21,7 @@
unit uUtils;
interface
-uses uTypes, uFloat, GLunit;
+uses uTypes, uFloat;
procedure SplitBySpace(var a, b: shortstring);
procedure SplitByChar(var a, b: shortstring; c: char);
@@ -41,7 +41,7 @@
function StrToInt(s: shortstring): LongInt;
function FloatToStr(n: hwFloat): shortstring;
-function DxDy2Angle(const _dY, _dX: hwFloat): GLfloat; inline;
+function DxDy2Angle(const _dY, _dX: hwFloat): real; inline;
function DxDy2Angle32(const _dY, _dX: hwFloat): LongInt;
function DxDy2AttackAngle(const _dY, _dX: hwFloat): LongInt;
function DxDy2AttackAnglef(const _dY, _dX: extended): LongInt;
@@ -200,7 +200,7 @@
end;
-function DxDy2Angle(const _dY, _dX: hwFloat): GLfloat; inline;
+function DxDy2Angle(const _dY, _dX: hwFloat): real; inline;
var dY, dX: Extended;
begin
dY:= hwFloat2Float(_dY);
@@ -505,6 +505,20 @@
{$I+}
{$ENDIF}
+ //mobile stuff
+ mobileRecord.getScreenDPI:= @getScreenDPI; //TODO: define external function.
+{$IFDEF IPHONEOS}
+ mobileRecord.PerformRumble:= @AudioServicesPlaySystemSound;
+ mobileRecord.GameLoading:= @startLoadingIndicator;
+ mobileRecord.GameLoaded:= @stopLoadingIndicator;
+ mobileRecord.SaveLoadingEnded:= @saveFinishedSynching;
+{$ELSE}
+ mobileRecord.PerformRumble:= nil;
+ mobileRecord.GameLoading:= nil;
+ mobileRecord.GameLoaded:= nil;
+ mobileRecord.SaveLoadingEnded:= nil;
+{$ENDIF}
+
end;
procedure freeModule;
--- a/hedgewars/uVariables.pas Mon Jul 01 22:28:42 2013 +0300
+++ b/hedgewars/uVariables.pas Mon Jul 01 23:23:22 2013 +0300
@@ -21,7 +21,7 @@
unit uVariables;
interface
-uses SDLh, uTypes, uFloat, GLunit, uConsts, Math, uUtils;
+uses SDLh, uTypes, uFloat, GLunit, uConsts, Math;
var
/////// init flags ///////
@@ -2324,7 +2324,7 @@
procedure freeModule;
implementation
-
+uses strutils;
procedure preInitModule;
begin
@@ -2366,10 +2366,9 @@
end;
procedure initModule;
-var s: ShortString;
begin
- cLocale:= cLocaleFName;
- SplitByChar(cLocale, s, '.');
+ // TODO: we could just have one cLocale variables and drop strutils
+ cLocale:= ExtractDelimited(0, cLocaleFName, StdWordDelims);
cFlattenFlakes := false;
cFlattenClouds := false;
@@ -2415,10 +2414,10 @@
WaterOpacity:= $80;
- cDrownSpeed.QWordValue := 257698038; // 0.06
+ cDrownSpeed.QWordValue := 257698038; // 0.06
cDrownSpeedf := 0.06;
cMaxWindSpeed.QWordValue:= 1073742; // 0.00025
- cWindSpeed.QWordValue := 0; // 0.0
+ cWindSpeed.QWordValue := 0; // 0.0
cWindSpeedf := 0.0;
cGravity := cMaxWindSpeed * 2;
cGravityf := 0.00025 * 2;
@@ -2537,19 +2536,6 @@
cMapName:= '';
LuaTemplateNumber:= 0;
-
- mobileRecord.getScreenDPI:= @getScreenDPI; //TODO: define external function.
- {$IFDEF IPHONEOS}
- mobileRecord.PerformRumble:= @AudioServicesPlaySystemSound;
- mobileRecord.GameLoading:= @startLoadingIndicator;
- mobileRecord.GameLoaded:= @stopLoadingIndicator;
- mobileRecord.SaveLoadingEnded:= @saveFinishedSynching;
- {$ELSE}
- mobileRecord.PerformRumble:= nil;
- mobileRecord.GameLoading:= nil;
- mobileRecord.GameLoaded:= nil;
- mobileRecord.SaveLoadingEnded:= nil;
- {$ENDIF}
end;
procedure freeModule;
--- a/hedgewars/uVisualGears.pas Mon Jul 01 22:28:42 2013 +0300
+++ b/hedgewars/uVisualGears.pas Mon Jul 01 23:23:22 2013 +0300
@@ -29,19 +29,13 @@
* E.g.: background flakes, visual effects: explosion, smoke trails, etc.
*)
interface
-uses uConsts, uFloat, GLunit, uTypes, uWorld;
+uses uConsts, GLunit, uTypes;
procedure initModule;
procedure freeModule;
-function AddVisualGear(X, Y: LongInt; Kind: TVisualGearType): PVisualGear; inline;
-function AddVisualGear(X, Y: LongInt; Kind: TVisualGearType; State: LongWord): PVisualGear; inline;
-function AddVisualGear(X, Y: LongInt; Kind: TVisualGearType; State: LongWord; Critical: Boolean): PVisualGear;
-
procedure ProcessVisualGears(Steps: Longword);
procedure DrawVisualGears(Layer: LongWord);
-procedure DeleteVisualGear(Gear: PVisualGear);
-function VisualGearByUID(uid : Longword) : PVisualGear;
procedure AddClouds;
procedure AddFlakes;
@@ -53,17 +47,8 @@
procedure KickFlakes(Radius, X, Y: LongInt);
implementation
-uses uSound, uVariables, uTextures, uRender, Math, uRenderUtils, uStore, uUtils;
-
-const
- cExplFrameTicks = 110;
- //cSmokeZ = 499;
-var VGCounter: LongWord;
- VisualGearLayers: array[0..6] of PVisualGear;
-
-// For better maintainability the step handlers of visual gears are stored
-// in a separate file.
-{$INCLUDE "VGSHandlers.inc"}
+uses uVariables, uRender, Math, uRenderUtils, uStore, uUtils
+ , uVisualGearsList;
procedure AddDamageTag(X, Y, Damage, Color: LongWord);
var s: shortstring;
@@ -84,436 +69,6 @@
// ==================================================================
-// ==================================================================
-const doStepHandlers: array[TVisualGearType] of TVGearStepProcedure =
- (
- @doStepFlake,
- @doStepCloud,
- @doStepExpl,
- @doStepExpl,
- @doStepFire,
- @doStepSmallDamage,
- @doStepTeamHealthSorter,
- @doStepSpeechBubble,
- @doStepBubble,
- @doStepSteam,
- @doStepAmmo,
- @doStepSmoke,
- @doStepSmoke,
- @doStepShell,
- @doStepDust,
- @doStepSplash,
- @doStepDroplet,
- @doStepSmokeRing,
- @doStepBeeTrace,
- @doStepEgg,
- @doStepFeather,
- @doStepHealthTag,
- @doStepSmokeTrace,
- @doStepSmokeTrace,
- @doStepExplosion,
- @doStepBigExplosion,
- @doStepChunk,
- @doStepNote,
- @doStepLineTrail,
- @doStepBulletHit,
- @doStepCircle,
- @doStepSmoothWindBar,
- @doStepStraightShot
- );
-
-function AddVisualGear(X, Y: LongInt; Kind: TVisualGearType): PVisualGear; inline;
-begin
- AddVisualGear:= AddVisualGear(X, Y, Kind, 0, false);
-end;
-
-function AddVisualGear(X, Y: LongInt; Kind: TVisualGearType; State: LongWord): PVisualGear; inline;
-begin
- AddVisualGear:= AddVisualGear(X, Y, Kind, State, false);
-end;
-
-function AddVisualGear(X, Y: LongInt; Kind: TVisualGearType; State: LongWord; Critical: Boolean): PVisualGear;
-var gear: PVisualGear;
- t: Longword;
- sp: real;
-begin
-AddVisualGear:= nil;
-if ((GameType = gmtSave) or (fastUntilLag and (GameType = gmtNet)) or fastScrolling) and // we are scrolling now
- ((Kind <> vgtCloud) and (not Critical)) then
- exit;
-
-if ((cReducedQuality and rqAntiBoom) <> 0) and
- (not Critical) and
- (not (Kind in
- [vgtTeamHealthSorter,
- vgtSmallDamageTag,
- vgtSpeechBubble,
- vgtHealthTag,
- vgtExplosion,
- vgtSmokeTrace,
- vgtEvilTrace,
- vgtNote,
- vgtSmoothWindBar])) then
-
- exit;
-
-inc(VGCounter);
-New(gear);
-FillChar(gear^, sizeof(TVisualGear), 0);
-gear^.X:= real(X);
-gear^.Y:= real(Y);
-gear^.Kind := Kind;
-gear^.doStep:= doStepHandlers[Kind];
-gear^.State:= 0;
-gear^.Tint:= $FFFFFFFF;
-gear^.uid:= VGCounter;
-gear^.Layer:= 0;
-
-with gear^ do
- case Kind of
- vgtFlake:
- begin
- Timer:= 0;
- tdX:= 0;
- tdY:= 0;
- Scale:= 1.0;
- if SuddenDeathDmg then
- begin
- FrameTicks:= random(vobSDFrameTicks);
- Frame:= random(vobSDFramesCount);
- end
- else
- begin
- FrameTicks:= random(vobFrameTicks);
- Frame:= random(vobFramesCount);
- end;
- Angle:= random(360);
- dx:= 0.0000038654705 * random(10000);
- dy:= 0.000003506096 * random(7000);
- if random(2) = 0 then
- dx := -dx;
- if SuddenDeathDmg then
- dAngle:= (random(2) * 2 - 1) * (vobSDVelocity + random(vobSDVelocity)) / 1000
- else
- dAngle:= (random(2) * 2 - 1) * (vobVelocity + random(vobVelocity)) / 1000
- end;
- vgtCloud:
- begin
- Frame:= random(4);
- dx:= 0.5 + 0.1 * random(5); // how much the cloud will be affected by wind
- timer:= random(4096);
- Scale:= 1.0
- end;
- vgtExplPart,
- vgtExplPart2:
- begin
- t:= random(1024);
- sp:= 0.001 * (random(95) + 70);
- dx:= hwFloat2Float(AngleSin(t)) * sp;
- dy:= hwFloat2Float(AngleCos(t)) * sp;
- if random(2) = 0 then
- dx := -dx;
- if random(2) = 0 then
- dy := -dy;
- Frame:= 7 - random(3);
- FrameTicks:= cExplFrameTicks
- end;
- vgtFire:
- begin
- t:= random(1024);
- sp:= 0.001 * (random(85) + 95);
- dx:= hwFloat2Float(AngleSin(t)) * sp;
- dy:= hwFloat2Float(AngleCos(t)) * sp;
- if random(2) = 0 then
- dx := -dx;
- if random(2) = 0 then
- dy := -dy;
- FrameTicks:= 650 + random(250);
- Frame:= random(8)
- end;
- vgtEgg:
- begin
- t:= random(1024);
- sp:= 0.001 * (random(85) + 95);
- dx:= hwFloat2Float(AngleSin(t)) * sp;
- dy:= hwFloat2Float(AngleCos(t)) * sp;
- if random(2) = 0 then
- dx := -dx;
- if random(2) = 0 then
- dy := -dy;
- FrameTicks:= 650 + random(250);
- Frame:= 1
- end;
- vgtShell: FrameTicks:= 500;
- vgtSmallDamageTag:
- begin
- gear^.FrameTicks:= 1100
- end;
- vgtBubble:
- begin
- dx:= 0.0000038654705 * random(10000);
- dy:= 0;
- if random(2) = 0 then
- dx := -dx;
- FrameTicks:= 250 + random(1751);
- Frame:= random(5)
- end;
- vgtSteam:
- begin
- dx:= 0.0000038654705 * random(10000);
- dy:= 0.001 * (random(85) + 95);
- if random(2) = 0 then
- dx := -dx;
- Frame:= 7 - random(3);
- FrameTicks:= cExplFrameTicks * 2;
- end;
- vgtAmmo:
- begin
- alpha:= 1.0;
- scale:= 1.0
- end;
- vgtSmokeWhite,
- vgtSmoke:
- begin
- Scale:= 1.0;
- dx:= 0.0002 * (random(45) + 10);
- dy:= 0.0002 * (random(45) + 10);
- if random(2) = 0 then
- dx := -dx;
- Frame:= 7 - random(2);
- FrameTicks:= cExplFrameTicks * 2;
- end;
- vgtDust:
- begin
- dx:= 0.005 * (random(15) + 10);
- dy:= 0.001 * (random(40) + 20);
- if random(2) = 0 then dx := -dx;
- if random(2) = 0 then Tag:= 1
- else Tag:= -1;
- Frame:= 7 - random(2);
- FrameTicks:= random(20) + 15;
- end;
- vgtSplash:
- begin
- dx:= 0;
- dy:= 0;
- FrameTicks:= 740;
- Frame:= 19;
- Scale:= 0.75;
- Timer:= 1;
- end;
- vgtDroplet:
- begin
- dx:= 0.001 * (random(180) - 90);
- dy:= -0.001 * (random(160) + 40);
- FrameTicks:= 250 + random(1751);
- Frame:= random(3)
- end;
- vgtBeeTrace:
- begin
- FrameTicks:= 1000;
- Frame:= random(16);
- end;
- vgtSmokeRing:
- begin
- dx:= 0;
- dy:= 0;
- FrameTicks:= 600;
- Timer:= 0;
- Frame:= 0;
- scale:= 0.6;
- alpha:= 1;
- angle:= random(360);
- end;
- vgtFeather:
- begin
- t:= random(1024);
- sp:= 0.001 * (random(85) + 95);
- dx:= hwFloat2Float(AngleSin(t)) * sp;
- dy:= hwFloat2Float(AngleCos(t)) * sp;
- if random(2) = 0 then
- dx := -dx;
- if random(2) = 0 then
- dy := -dy;
- FrameTicks:= 650 + random(250);
- Frame:= 1
- end;
- vgtHealthTag:
- begin
- Frame:= 0;
- Timer:= 1500;
- dY:= -0.08;
- dX:= 0;
- //gear^.Z:= 2002;
- end;
- vgtSmokeTrace,
- vgtEvilTrace:
- begin
- gear^.X:= gear^.X - 16;
- gear^.Y:= gear^.Y - 16;
- gear^.State:= 8;
- //gear^.Z:= cSmokeZ
- end;
-vgtBigExplosion:
- begin
- gear^.Angle:= random(360);
- end;
- vgtChunk:
- begin
- gear^.Frame:= random(4);
- t:= random(1024);
- sp:= 0.001 * (random(85) + 47);
- dx:= hwFloat2Float(AngleSin(t)) * sp;
- dy:= hwFloat2Float(AngleCos(t)) * sp * -2;
- if random(2) = 0 then
- dx := -dx;
- end;
- vgtNote:
- begin
- dx:= 0.005 * (random(15) + 10);
- dy:= -0.001 * (random(40) + 20);
- if random(2) = 0 then
- dx := -dx;
- Frame:= random(4);
- FrameTicks:= random(2000) + 1500;
- end;
- vgtBulletHit:
- begin
- dx:= 0;
- dy:= 0;
- FrameTicks:= 350;
- Frame:= 7;
- Angle:= 0;
- end;
-vgtSmoothWindBar:
- begin
- Angle:= hwFloat2Float(cMaxWindSpeed)*2 / 1440; // seems rate below is supposed to change wind bar at 1px per 10ms. Max time, 1440ms. This tries to match the rate of change
- Tag:= hwRound(cWindSpeed * 72 / cMaxWindSpeed);
- end;
- vgtStraightShot:
- begin
- Angle:= 0;
- Scale:= 1.0;
- dx:= 0.001 * random(45);
- dy:= 0.001 * (random(20) + 25);
- State:= ord(sprHealth);
- if random(2) = 0 then
- dx := -dx;
- Frame:= 0;
- FrameTicks:= random(750) + 1250;
- State:= ord(sprSnowDust);
- end;
- end;
-
-if State <> 0 then
- gear^.State:= State;
-
-case Gear^.Kind of
- vgtFlake: if cFlattenFlakes then
- gear^.Layer:= 0
- else if random(3) = 0 then
- begin
- gear^.Scale:= 0.5;
- gear^.Layer:= 0 // 33% - far back
- end
- else if random(3) = 0 then
- begin
- gear^.Scale:= 0.8;
- gear^.Layer:= 4 // 22% - mid-distance
- end
- else if random(3) <> 0 then
- gear^.Layer:= 5 // 30% - just behind land
- else if random(2) = 0 then
- gear^.Layer:= 6 // 7% - just in front of land
- else
- begin
- gear^.Scale:= 1.5;
- gear^.Layer:= 2; // 7% - close up
- end;
-
- vgtCloud: if cFlattenClouds then gear^.Layer:= 5
- else if random(3) = 0 then
- begin
- gear^.Scale:= 0.25;
- gear^.Layer:= 0
- end
- else if random(2) = 0 then
- gear^.Layer:= 5
- else
- begin
- gear^.Scale:= 0.4;
- gear^.Layer:= 4
- end;
-
- // 0: this layer is very distant in the background when in stereo
- vgtTeamHealthSorter,
- vgtSmoothWindBar: gear^.Layer:= 0;
-
-
- // 1: this layer is on the land level (which is close but behind the screen plane) when stereo
- vgtSmokeTrace,
- vgtEvilTrace,
- vgtLineTrail,
- vgtSmoke,
- vgtSmokeWhite,
- vgtDust,
- vgtFire,
- vgtSplash,
- vgtDroplet,
- vgtBubble: gear^.Layer:= 1;
-
- // 3: this layer is on the screen plane (depth = 0) when stereo
- vgtSpeechBubble,
- vgtSmallDamageTag,
- vgtHealthTag,
- vgtStraightShot,
- vgtChunk: gear^.Layer:= 3;
-
- // 2: this layer is outside the screen when stereo
- vgtExplosion,
- vgtBigExplosion,
- vgtExplPart,
- vgtExplPart2,
- vgtSteam,
- vgtAmmo,
- vgtShell,
- vgtFeather,
- vgtEgg,
- vgtBeeTrace,
- vgtSmokeRing,
- vgtNote,
- vgtBulletHit,
- vgtCircle: gear^.Layer:= 2
-end;
-
-if VisualGearLayers[gear^.Layer] <> nil then
- begin
- VisualGearLayers[gear^.Layer]^.PrevGear:= gear;
- gear^.NextGear:= VisualGearLayers[gear^.Layer]
- end;
-VisualGearLayers[gear^.Layer]:= gear;
-
-AddVisualGear:= gear;
-end;
-
-procedure DeleteVisualGear(Gear: PVisualGear);
-begin
- FreeTexture(Gear^.Tex);
- Gear^.Tex:= nil;
-
- if Gear^.NextGear <> nil then
- Gear^.NextGear^.PrevGear:= Gear^.PrevGear;
- if Gear^.PrevGear <> nil then
- Gear^.PrevGear^.NextGear:= Gear^.NextGear
- else
- VisualGearLayers[Gear^.Layer]:= Gear^.NextGear;
-
- if lastVisualGearByUID = Gear then
- lastVisualGearByUID:= nil;
-
- Dispose(Gear);
-end;
-
procedure ProcessVisualGears(Steps: Longword);
var Gear, t: PVisualGear;
i: LongWord;
@@ -900,35 +455,6 @@
end;
end;
-function VisualGearByUID(uid : Longword) : PVisualGear;
-var vg: PVisualGear;
- i: LongWord;
-begin
-VisualGearByUID:= nil;
-if uid = 0 then
- exit;
-if (lastVisualGearByUID <> nil) and (lastVisualGearByUID^.uid = uid) then
- begin
- VisualGearByUID:= lastVisualGearByUID;
- exit
- end;
-// search in an order that is more likely to return layers they actually use. Could perhaps track statistically AddVisualGear in uScript, since that is most likely the ones they want
-for i:= 2 to 5 do
- begin
- vg:= VisualGearLayers[i mod 4];
- while vg <> nil do
- begin
- if vg^.uid = uid then
- begin
- lastVisualGearByUID:= vg;
- VisualGearByUID:= vg;
- exit
- end;
- vg:= vg^.NextGear
- end
- end
-end;
-
procedure AddClouds;
var i: LongInt;
begin
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hedgewars/uVisualGearsHandlers.pas Mon Jul 01 23:23:22 2013 +0300
@@ -0,0 +1,897 @@
+(*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *)
+
+(*
+ * This file contains the step handlers for visual gears.
+ *
+ * Since the effects of visual gears do not affect the course of the game,
+ * no "synchronization" between players is required.
+ * => The usage of safe functions or data types (e.g. GetRandom() or hwFloat)
+ * is usually not necessary and therefore undesirable.
+ *)
+
+{$INCLUDE "options.inc"}
+
+unit uVisualGearsHandlers;
+
+interface
+uses uTypes;
+
+var doStepHandlers: array[TVisualGearType] of TVGearStepProcedure;
+
+procedure doStepFlake(Gear: PVisualGear; Steps: Longword);
+procedure doStepBeeTrace(Gear: PVisualGear; Steps: Longword);
+procedure doStepCloud(Gear: PVisualGear; Steps: Longword);
+procedure doStepExpl(Gear: PVisualGear; Steps: Longword);
+procedure doStepNote(Gear: PVisualGear; Steps: Longword);
+procedure doStepLineTrail(Gear: PVisualGear; Steps: Longword);
+procedure doStepEgg(Gear: PVisualGear; Steps: Longword);
+procedure doStepFire(Gear: PVisualGear; Steps: Longword);
+procedure doStepShell(Gear: PVisualGear; Steps: Longword);
+procedure doStepSmallDamage(Gear: PVisualGear; Steps: Longword);
+procedure doStepBubble(Gear: PVisualGear; Steps: Longword);
+procedure doStepSteam(Gear: PVisualGear; Steps: Longword);
+procedure doStepAmmo(Gear: PVisualGear; Steps: Longword);
+procedure doStepSmoke(Gear: PVisualGear; Steps: Longword);
+procedure doStepDust(Gear: PVisualGear; Steps: Longword);
+procedure doStepSplash(Gear: PVisualGear; Steps: Longword);
+procedure doStepDroplet(Gear: PVisualGear; Steps: Longword);
+procedure doStepSmokeRing(Gear: PVisualGear; Steps: Longword);
+procedure doStepFeather(Gear: PVisualGear; Steps: Longword);
+procedure doStepTeamHealthSorterWork(Gear: PVisualGear; Steps: Longword);
+procedure doStepTeamHealthSorter(Gear: PVisualGear; Steps: Longword);
+procedure doStepSpeechBubbleWork(Gear: PVisualGear; Steps: Longword);
+procedure doStepSpeechBubble(Gear: PVisualGear; Steps: Longword);
+procedure doStepHealthTagWork(Gear: PVisualGear; Steps: Longword);
+procedure doStepHealthTagWorkUnderWater(Gear: PVisualGear; Steps: Longword);
+procedure doStepHealthTag(Gear: PVisualGear; Steps: Longword);
+procedure doStepSmokeTrace(Gear: PVisualGear; Steps: Longword);
+procedure doStepExplosionWork(Gear: PVisualGear; Steps: Longword);
+procedure doStepExplosion(Gear: PVisualGear; Steps: Longword);
+procedure doStepBigExplosionWork(Gear: PVisualGear; Steps: Longword);
+procedure doStepBigExplosion(Gear: PVisualGear; Steps: Longword);
+procedure doStepChunk(Gear: PVisualGear; Steps: Longword);
+procedure doStepBulletHit(Gear: PVisualGear; Steps: Longword);
+procedure doStepCircle(Gear: PVisualGear; Steps: Longword);
+procedure doStepSmoothWindBar(Gear: PVisualGear; Steps: Longword);
+procedure doStepStraightShot(Gear: PVisualGear; Steps: Longword);
+
+procedure initModule;
+
+implementation
+uses uVariables, Math, uConsts, uVisualGearsList, uFloat, uSound, uRenderUtils, uWorld;
+
+procedure doStepFlake(Gear: PVisualGear; Steps: Longword);
+var sign: real;
+ moved: boolean;
+begin
+if vobCount = 0 then exit;
+
+sign:= 1;
+with Gear^ do
+ begin
+ inc(FrameTicks, Steps);
+ if not SuddenDeathDmg and (FrameTicks > vobFrameTicks) then
+ begin
+ dec(FrameTicks, vobFrameTicks);
+ inc(Frame);
+ if Frame = vobFramesCount then
+ Frame:= 0
+ end
+ else if SuddenDeathDmg and (FrameTicks > vobSDFrameTicks) then
+ begin
+ dec(FrameTicks, vobSDFrameTicks);
+ inc(Frame);
+ if Frame = vobSDFramesCount then
+ Frame:= 0
+ end;
+ X:= X + (cWindSpeedf * 400 + dX + tdX) * Steps * Gear^.Scale;
+ if SuddenDeathDmg then
+ Y:= Y + (dY + tdY + cGravityf * vobSDFallSpeed) * Steps * Gear^.Scale
+ else
+ Y:= Y + (dY + tdY + cGravityf * vobFallSpeed) * Steps * Gear^.Scale;
+ Angle:= Angle + dAngle * Steps;
+ if Angle > 360 then
+ Angle:= Angle - 360
+ else
+ if Angle < - 360 then
+ Angle:= Angle + 360;
+
+
+ if (round(X) >= cLeftScreenBorder)
+ and (round(X) <= cRightScreenBorder)
+ and (round(Y) - 75 <= LAND_HEIGHT)
+ and (Timer > 0) and (Timer-Steps > 0) then
+ begin
+ if tdX > 0 then
+ sign := 1
+ else
+ sign:= -1;
+ tdX:= tdX - 0.005*Steps*sign;
+ if ((sign < 0) and (tdX > 0)) or ((sign > 0) and (tdX < 0)) then
+ tdX:= 0;
+ if tdX > 0 then
+ sign := 1
+ else
+ sign:= -1;
+ tdY:= tdY - 0.005*Steps*sign;
+ if ((sign < 0) and (tdY > 0)) or ((sign > 0) and (tdY < 0)) then
+ tdY:= 0;
+ dec(Timer, Steps)
+ end
+ else
+ begin
+ moved:= false;
+ if round(X) < cLeftScreenBorder then
+ begin
+ X:= X + cScreenSpace;
+ moved:= true
+ end
+ else
+ if round(X) > cRightScreenBorder then
+ begin
+ X:= X - cScreenSpace;
+ moved:= true
+ end;
+ // if round(Y) < (LAND_HEIGHT - 1024 - 75) then Y:= Y + 25.0; // For if flag is set for flakes rising upwards?
+ if (Gear^.Layer = 2) and (round(Y) - 225 > LAND_HEIGHT) then
+ begin
+ X:= cLeftScreenBorder + random(cScreenSpace);
+ Y:= Y - (1024 + 250 + random(50)); // TODO - configure in theme (jellies for example could use limited range)
+ moved:= true
+ end
+ else if (Gear^.Layer <> 2) and (round(Y) + 50 > LAND_HEIGHT) then
+ begin
+ X:= cLeftScreenBorder + random(cScreenSpace);
+ Y:= Y - (1024 + random(25));
+ moved:= true
+ end;
+ if moved then
+ begin
+ Angle:= random(360);
+ dx:= 0.0000038654705 * random(10000);
+ dy:= 0.000003506096 * random(7000);
+ if random(2) = 0 then dx := -dx
+ end;
+ Timer:= 0;
+ tdX:= 0;
+ tdY:= 0
+ end;
+ end;
+
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepBeeTrace(Gear: PVisualGear; Steps: Longword);
+begin
+if Gear^.FrameTicks > Steps then
+ dec(Gear^.FrameTicks, Steps)
+else
+ DeleteVisualGear(Gear);
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepCloud(Gear: PVisualGear; Steps: Longword);
+var s: Longword;
+ t: real;
+begin
+Gear^.X:= Gear^.X + (cWindSpeedf * 750 * Gear^.dX * Gear^.Scale) * Steps;
+
+// up-and-down-bounce magic
+s := (GameTicks + Gear^.Timer) mod 4096;
+t := 8 * Gear^.Scale * hwFloat2Float(AngleSin(s mod 2048));
+if (s < 2048) then t := -t;
+
+Gear^.Y := LAND_HEIGHT - 1184 + LongInt(Gear^.Timer mod 8) + t;
+
+if round(Gear^.X) < cLeftScreenBorder then
+ Gear^.X:= Gear^.X + cScreenSpace
+else
+ if round(Gear^.X) > cRightScreenBorder then
+ Gear^.X:= Gear^.X - cScreenSpace
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepExpl(Gear: PVisualGear; Steps: Longword);
+var s: LongInt;
+begin
+s:= min(Steps, cExplFrameTicks);
+
+Gear^.X:= Gear^.X + Gear^.dX * s;
+Gear^.Y:= Gear^.Y + Gear^.dY * s;
+//Gear^.dY:= Gear^.dY + cGravityf;
+
+if Gear^.FrameTicks <= Steps then
+ if Gear^.Frame = 0 then
+ DeleteVisualGear(Gear)
+ else
+ begin
+ dec(Gear^.Frame);
+ Gear^.FrameTicks:= cExplFrameTicks
+ end
+ else dec(Gear^.FrameTicks, Steps)
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepNote(Gear: PVisualGear; Steps: Longword);
+begin
+Gear^.X:= Gear^.X + Gear^.dX * Steps;
+
+Gear^.Y:= Gear^.Y + Gear^.dY * Steps;
+Gear^.dY:= Gear^.dY + cGravityf * Steps / 2;
+
+Gear^.Angle:= Gear^.Angle + (Gear^.Frame + 1) * Steps / 10;
+while Gear^.Angle > cMaxAngle do
+ Gear^.Angle:= Gear^.Angle - cMaxAngle;
+
+if Gear^.FrameTicks <= Steps then
+ DeleteVisualGear(Gear)
+else
+ dec(Gear^.FrameTicks, Steps)
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepLineTrail(Gear: PVisualGear; Steps: Longword);
+begin
+Steps := Steps;
+if Gear^.Timer <= Steps then
+ DeleteVisualGear(Gear)
+else
+ dec(Gear^.Timer, Steps)
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepEgg(Gear: PVisualGear; Steps: Longword);
+begin
+Gear^.X:= Gear^.X + Gear^.dX * Steps;
+
+Gear^.Y:= Gear^.Y + Gear^.dY * Steps;
+Gear^.dY:= Gear^.dY + cGravityf * Steps;
+
+Gear^.Angle:= round(Gear^.Angle + Steps) mod cMaxAngle;
+
+if Gear^.FrameTicks <= Steps then
+ begin
+ DeleteVisualGear(Gear);
+ exit
+ end
+else
+ dec(Gear^.FrameTicks, Steps);
+
+if Gear^.FrameTicks < $FF then
+ Gear^.Tint:= (Gear^.Tint and $FFFFFF00) or Gear^.FrameTicks
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepFire(Gear: PVisualGear; Steps: Longword);
+var vgt: PVisualGear;
+begin
+Gear^.X:= Gear^.X + Gear^.dX * Steps;
+
+Gear^.Y:= Gear^.Y + Gear^.dY * Steps;// + cGravityf * (Steps * Steps);
+if (Gear^.State and gstTmpFlag) = 0 then
+ begin
+ Gear^.dY:= Gear^.dY + cGravityf * Steps;
+ if ((GameTicks mod 200) < Steps + 1) then
+ begin
+ vgt:= AddVisualGear(round(Gear^.X), round(Gear^.Y), vgtFire);
+ if vgt <> nil then
+ begin
+ vgt^.dx:= 0;
+ vgt^.dy:= 0;
+ vgt^.State:= gstTmpFlag;
+ end;
+ end
+ end
+else
+ inc(Steps, Steps);
+
+if Gear^.FrameTicks <= Steps then
+ DeleteVisualGear(Gear)
+else
+ dec(Gear^.FrameTicks, Steps)
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepShell(Gear: PVisualGear; Steps: Longword);
+begin
+Gear^.X:= Gear^.X + Gear^.dX * Steps;
+
+Gear^.Y:= Gear^.Y + Gear^.dY * Steps;
+Gear^.dY:= Gear^.dY + cGravityf * Steps;
+
+Gear^.Angle:= round(Gear^.Angle + Steps) mod cMaxAngle;
+
+if Gear^.FrameTicks <= Steps then
+ DeleteVisualGear(Gear)
+else
+ dec(Gear^.FrameTicks, Steps)
+end;
+
+procedure doStepSmallDamage(Gear: PVisualGear; Steps: Longword);
+begin
+Gear^.Y:= Gear^.Y - 0.02 * Steps;
+
+if Gear^.FrameTicks <= Steps then
+ DeleteVisualGear(Gear)
+else
+ dec(Gear^.FrameTicks, Steps)
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepBubble(Gear: PVisualGear; Steps: Longword);
+begin
+Gear^.X:= Gear^.X + Gear^.dX * Steps;
+Gear^.Y:= Gear^.Y + Gear^.dY * Steps;
+Gear^.Y:= Gear^.Y - cDrownSpeedf * Steps;
+Gear^.dX := Gear^.dX / (1.001 * Steps);
+Gear^.dY := Gear^.dY / (1.001 * Steps);
+
+if (Gear^.FrameTicks <= Steps) or (round(Gear^.Y) < cWaterLine) then
+ DeleteVisualGear(Gear)
+else
+ dec(Gear^.FrameTicks, Steps)
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepSteam(Gear: PVisualGear; Steps: Longword);
+begin
+Gear^.X:= Gear^.X + (cWindSpeedf * 100 + Gear^.dX) * Steps;
+Gear^.Y:= Gear^.Y - cDrownSpeedf * Steps;
+
+if Gear^.FrameTicks <= Steps then
+ if Gear^.Frame = 0 then
+ DeleteVisualGear(Gear)
+ else
+ begin
+ if Random(2) = 0 then
+ dec(Gear^.Frame);
+ Gear^.FrameTicks:= cExplFrameTicks
+ end
+else dec(Gear^.FrameTicks, Steps)
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepAmmo(Gear: PVisualGear; Steps: Longword);
+begin
+Gear^.Y:= Gear^.Y - cDrownSpeedf * Steps;
+
+Gear^.scale:= Gear^.scale + 0.0025 * Steps;
+Gear^.alpha:= Gear^.alpha - 0.0015 * Steps;
+
+if Gear^.alpha < 0 then
+ DeleteVisualGear(Gear)
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepSmoke(Gear: PVisualGear; Steps: Longword);
+begin
+Gear^.X:= Gear^.X + (cWindSpeedf + Gear^.dX) * Steps;
+Gear^.Y:= Gear^.Y - (cDrownSpeedf + Gear^.dY) * Steps;
+
+Gear^.dX := Gear^.dX + (cWindSpeedf * 0.3 * Steps);
+//Gear^.dY := Gear^.dY - (cDrownSpeedf * 0.995);
+
+if Gear^.FrameTicks <= Steps then
+ if Gear^.Frame = 0 then
+ DeleteVisualGear(Gear)
+ else
+ begin
+ if Random(2) = 0 then
+ dec(Gear^.Frame);
+ Gear^.FrameTicks:= cExplFrameTicks
+ end
+ else dec(Gear^.FrameTicks, Steps)
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepDust(Gear: PVisualGear; Steps: Longword);
+begin
+Gear^.X:= Gear^.X + (cWindSpeedf + (cWindSpeedf * 0.03 * Steps) + Gear^.dX) * Steps;
+Gear^.Y:= Gear^.Y - (Gear^.dY) * Steps;
+
+Gear^.dX := Gear^.dX - (Gear^.dX * 0.005 * Steps);
+Gear^.dY := Gear^.dY - (cDrownSpeedf * 0.001 * Steps);
+
+if Gear^.FrameTicks <= Steps then
+ if Gear^.Frame = 0 then
+ DeleteVisualGear(Gear)
+ else
+ begin
+ dec(Gear^.Frame);
+ Gear^.FrameTicks:= cExplFrameTicks
+ end
+ else dec(Gear^.FrameTicks, Steps)
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepSplash(Gear: PVisualGear; Steps: Longword);
+begin
+if Gear^.FrameTicks <= Steps then
+ DeleteVisualGear(Gear)
+else
+ dec(Gear^.FrameTicks, Steps);
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepDroplet(Gear: PVisualGear; Steps: Longword);
+begin
+Gear^.X:= Gear^.X + Gear^.dX * Steps;
+
+Gear^.Y:= Gear^.Y + Gear^.dY * Steps;
+Gear^.dY:= Gear^.dY + cGravityf * Steps;
+
+if round(Gear^.Y) > cWaterLine then
+ begin
+ DeleteVisualGear(Gear);
+ PlaySound(TSound(ord(sndDroplet1) + Random(3)));
+ end;
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepSmokeRing(Gear: PVisualGear; Steps: Longword);
+begin
+inc(Gear^.Timer, Steps);
+if Gear^.Timer >= Gear^.FrameTicks then
+ DeleteVisualGear(Gear)
+else
+ begin
+ Gear^.scale := 1.25 * (-power(2, -10 * Int(Gear^.Timer)/Gear^.FrameTicks) + 1) + 0.4;
+ Gear^.alpha := 1 - power(Gear^.Timer / 350, 4);
+ if Gear^.alpha < 0 then
+ Gear^.alpha:= 0;
+ end;
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepFeather(Gear: PVisualGear; Steps: Longword);
+begin
+Gear^.X:= Gear^.X + Gear^.dX * Steps;
+
+Gear^.Y:= Gear^.Y + Gear^.dY * Steps;
+Gear^.dY:= Gear^.dY + cGravityf * Steps;
+
+Gear^.Angle:= round(Gear^.Angle + Steps) mod cMaxAngle;
+
+if Gear^.FrameTicks <= Steps then
+ DeleteVisualGear(Gear)
+else
+ dec(Gear^.FrameTicks, Steps)
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+const cSorterWorkTime = 640;
+var thexchar: array[0..cMaxTeams] of
+ record
+ dy, ny, dw: LongInt;
+ team: PTeam;
+ SortFactor: QWord;
+ end;
+ currsorter: PVisualGear = nil;
+
+procedure doStepTeamHealthSorterWork(Gear: PVisualGear; Steps: Longword);
+var i, t: LongInt;
+begin
+for t:= 1 to min(Steps, Gear^.Timer) do
+ begin
+ dec(Gear^.Timer);
+ if (Gear^.Timer and 15) = 0 then
+ for i:= 0 to Pred(TeamsCount) do
+ with thexchar[i] do
+ begin
+ {$WARNINGS OFF}
+ team^.DrawHealthY:= ny + dy * LongInt(Gear^.Timer) div cSorterWorkTime;
+ team^.TeamHealthBarWidth:= team^.NewTeamHealthBarWidth + dw * LongInt(Gear^.Timer) div cSorterWorkTime;
+ {$WARNINGS ON}
+ end;
+ end;
+
+if (Gear^.Timer = 0) or (currsorter <> Gear) then
+ begin
+ if currsorter = Gear then
+ currsorter:= nil;
+ DeleteVisualGear(Gear);
+ exit
+ end
+end;
+
+procedure doStepTeamHealthSorter(Gear: PVisualGear; Steps: Longword);
+var i: Longword;
+ b: boolean;
+ t: LongInt;
+begin
+Steps:= Steps; // avoid compiler hint
+
+for t:= 0 to Pred(TeamsCount) do
+ with thexchar[t] do
+ begin
+ team:= TeamsArray[t];
+ dy:= team^.DrawHealthY;
+ dw:= team^.TeamHealthBarWidth - team^.NewTeamHealthBarWidth;
+ if team^.TeamHealth > 0 then
+ begin
+ SortFactor:= team^.Clan^.ClanHealth;
+ SortFactor:= (SortFactor shl 3) + team^.Clan^.ClanIndex;
+ SortFactor:= (SortFactor shl 30) + team^.TeamHealth;
+ end
+ else
+ SortFactor:= 0;
+ end;
+
+if TeamsCount > 1 then
+ repeat
+ b:= true;
+ for t:= 0 to TeamsCount - 2 do
+ if (thexchar[t].SortFactor > thexchar[Succ(t)].SortFactor) then
+ begin
+ thexchar[cMaxTeams]:= thexchar[t];
+ thexchar[t]:= thexchar[Succ(t)];
+ thexchar[Succ(t)]:= thexchar[cMaxTeams];
+ b:= false
+ end
+ until b;
+
+t:= - 4;
+for i:= 0 to Pred(TeamsCount) do
+ with thexchar[i] do
+ if team^.TeamHealth > 0 then
+ begin
+ dec(t, team^.HealthTex^.h + 2);
+ ny:= t;
+ dy:= dy - ny
+ end;
+
+Gear^.Timer:= cSorterWorkTime;
+Gear^.doStep:= @doStepTeamHealthSorterWork;
+currsorter:= Gear;
+//doStepTeamHealthSorterWork(Gear, Steps)
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepSpeechBubbleWork(Gear: PVisualGear; Steps: Longword);
+begin
+if Gear^.Timer > Steps then dec(Gear^.Timer, Steps) else Gear^.Timer:= 0;
+
+if (Gear^.Hedgehog^.Gear <> nil) then
+ begin
+ Gear^.X:= hwFloat2Float(Gear^.Hedgehog^.Gear^.X) + (Gear^.Tex^.w div 2 - Gear^.FrameTicks);
+ Gear^.Y:= hwFloat2Float(Gear^.Hedgehog^.Gear^.Y) - (16 + Gear^.Tex^.h);
+ end;
+
+if Gear^.Timer = 0 then
+ begin
+ if Gear^.Hedgehog^.SpeechGear = Gear then
+ Gear^.Hedgehog^.SpeechGear:= nil;
+ DeleteVisualGear(Gear)
+ end;
+end;
+
+procedure doStepSpeechBubble(Gear: PVisualGear; Steps: Longword);
+begin
+Steps:= Steps; // avoid compiler hint
+
+with Gear^.Hedgehog^ do
+ if SpeechGear <> nil then
+ SpeechGear^.Timer:= 0;
+
+Gear^.Hedgehog^.SpeechGear:= Gear;
+
+Gear^.Timer:= max(LongInt(Length(Gear^.Text)) * 150, 3000);
+
+Gear^.Tex:= RenderSpeechBubbleTex(Gear^.Text, Gear^.FrameTicks, fnt16);
+
+case Gear^.FrameTicks of
+ 1: Gear^.FrameTicks:= SpritesData[sprSpeechTail].Width-28;
+ 2: Gear^.FrameTicks:= SpritesData[sprThoughtTail].Width-20;
+ 3: Gear^.FrameTicks:= SpritesData[sprShoutTail].Width-10;
+ end;
+
+Gear^.doStep:= @doStepSpeechBubbleWork;
+
+Gear^.Y:= Gear^.Y - Gear^.Tex^.h
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepHealthTagWork(Gear: PVisualGear; Steps: Longword);
+begin
+if Steps > Gear^.Timer then
+ DeleteVisualGear(Gear)
+else
+ begin
+ dec(Gear^.Timer, Steps);
+ Gear^.Y:= Gear^.Y + Gear^.dY * Steps;
+ Gear^.X:= Gear^.X + Gear^.dX * Steps
+ end;
+end;
+
+procedure doStepHealthTagWorkUnderWater(Gear: PVisualGear; Steps: Longword);
+begin
+if round(Gear^.Y) - 10 < cWaterLine then
+ DeleteVisualGear(Gear)
+else
+ Gear^.Y:= Gear^.Y - 0.08 * Steps;
+
+end;
+
+procedure doStepHealthTag(Gear: PVisualGear; Steps: Longword);
+var s: shortstring;
+begin
+s:= '';
+
+str(Gear^.State, s);
+if Gear^.Hedgehog <> nil then
+ Gear^.Tex:= RenderStringTex(s, Gear^.Hedgehog^.Team^.Clan^.Color, fnt16)
+else
+ Gear^.Tex:= RenderStringTex(s, cWhiteColor, fnt16);
+
+Gear^.doStep:= @doStepHealthTagWork;
+
+if (round(Gear^.Y) > cWaterLine) and (Gear^.Frame = 0) then
+ Gear^.doStep:= @doStepHealthTagWorkUnderWater;
+
+Gear^.Y:= Gear^.Y - Gear^.Tex^.h;
+
+if Steps > 1 then
+ Gear^.doStep(Gear, Steps-1);
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepSmokeTrace(Gear: PVisualGear; Steps: Longword);
+begin
+inc(Gear^.Timer, Steps );
+if Gear^.Timer > 64 then
+ begin
+ if Gear^.State = 0 then
+ begin
+ DeleteVisualGear(Gear);
+ exit;
+ end;
+ dec(Gear^.State, Gear^.Timer div 65);
+ Gear^.Timer:= Gear^.Timer mod 65;
+ end;
+Gear^.dX:= Gear^.dX + cWindSpeedf * Steps;
+Gear^.X:= Gear^.X + Gear^.dX;
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepExplosionWork(Gear: PVisualGear; Steps: Longword);
+begin
+inc(Gear^.Timer, Steps);
+if Gear^.Timer > 75 then
+ begin
+ inc(Gear^.State, Gear^.Timer div 76);
+ Gear^.Timer:= Gear^.Timer mod 76;
+ if Gear^.State > 5 then
+ DeleteVisualGear(Gear);
+ end;
+end;
+
+procedure doStepExplosion(Gear: PVisualGear; Steps: Longword);
+var i: LongWord;
+ gX,gY: LongInt;
+ vg: PVisualGear;
+begin
+gX:= round(Gear^.X);
+gY:= round(Gear^.Y);
+for i:= 0 to 31 do
+ begin
+ vg:= AddVisualGear(gX, gY, vgtFire);
+ if vg <> nil then
+ begin
+ vg^.State:= gstTmpFlag;
+ inc(vg^.FrameTicks, vg^.FrameTicks)
+ end
+ end;
+for i:= 0 to 8 do AddVisualGear(gX, gY, vgtExplPart);
+for i:= 0 to 8 do AddVisualGear(gX, gY, vgtExplPart2);
+Gear^.doStep:= @doStepExplosionWork;
+if Steps > 1 then
+ Gear^.doStep(Gear, Steps-1);
+end;
+
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepBigExplosionWork(Gear: PVisualGear; Steps: Longword);
+var maxMovement: LongInt;
+begin
+
+inc(Gear^.Timer, Steps);
+if (Gear^.Timer and 5) = 0 then
+ begin
+ maxMovement := max(1, 13 - ((Gear^.Timer * 15) div 250));
+ ShakeCamera(maxMovement);
+ end;
+
+if Gear^.Timer > 250 then
+ DeleteVisualGear(Gear);
+end;
+
+procedure doStepBigExplosion(Gear: PVisualGear; Steps: Longword);
+var i: LongWord;
+ gX,gY: LongInt;
+ vg: PVisualGear;
+begin
+//ScreenFade:= sfFromWhite;
+//ScreenFadeValue:= round(60 * zoom * zoom);
+//ScreenFadeSpeed:= 5;
+gX:= round(Gear^.X);
+gY:= round(Gear^.Y);
+AddVisualGear(gX, gY, vgtSmokeRing);
+for i:= 0 to 46 do
+ begin
+ vg:= AddVisualGear(gX, gY, vgtFire);
+ if vg <> nil then
+ begin
+ vg^.State:= gstTmpFlag;
+ inc(vg^.FrameTicks, vg^.FrameTicks)
+ end
+ end;
+for i:= 0 to 15 do
+ AddVisualGear(gX, gY, vgtExplPart);
+for i:= 0 to 15 do
+ AddVisualGear(gX, gY, vgtExplPart2);
+Gear^.doStep:= @doStepBigExplosionWork;
+if Steps > 1 then
+ Gear^.doStep(Gear, Steps-1);
+with mobileRecord do
+ if (performRumble <> nil) and (not fastUntilLag) then
+ performRumble(kSystemSoundID_Vibrate);
+end;
+
+procedure doStepChunk(Gear: PVisualGear; Steps: Longword);
+begin
+Gear^.X:= Gear^.X + Gear^.dX * Steps;
+
+Gear^.Y:= Gear^.Y + Gear^.dY * Steps;
+Gear^.dY:= Gear^.dY + cGravityf * Steps;
+
+Gear^.Angle:= round(Gear^.Angle + Steps) mod cMaxAngle;
+
+if (round(Gear^.Y) > cWaterLine) and ((cReducedQuality and rqPlainSplash) = 0) then
+ begin
+ AddVisualGear(round(Gear^.X), round(Gear^.Y), vgtDroplet);
+ DeleteVisualGear(Gear);
+ end
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepBulletHit(Gear: PVisualGear; Steps: Longword);
+begin
+if Gear^.FrameTicks <= Steps then
+ DeleteVisualGear(Gear)
+else
+ dec(Gear^.FrameTicks, Steps);
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepCircle(Gear: PVisualGear; Steps: Longword);
+var tmp: LongInt;
+ i: LongWord;
+begin
+with Gear^ do
+ if Frame <> 0 then
+ for i:= 1 to Steps do
+ begin
+ inc(FrameTicks);
+ if (FrameTicks mod Frame) = 0 then
+ begin
+ tmp:= Gear^.Tint and $FF;
+ if tdY >= 0 then
+ inc(tmp)
+ else
+ dec(tmp);
+ if tmp < round(dX) then
+ tdY:= 1;
+ if tmp > round(dY) then
+ tdY:= -1;
+ if tmp > 255 then
+ tmp := 255;
+ if tmp < 0 then
+ tmp := 0;
+ Gear^.Tint:= (Gear^.Tint and $FFFFFF00) or Longword(tmp)
+ end
+ end
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepSmoothWindBar(Gear: PVisualGear; Steps: Longword);
+begin
+inc(Gear^.Timer, Steps);
+
+while Gear^.Timer >= 10 do
+ begin
+ dec(Gear^.Timer, 10);
+ if WindBarWidth < Gear^.Tag then
+ inc(WindBarWidth)
+ else if WindBarWidth > Gear^.Tag then
+ dec(WindBarWidth);
+ end;
+if cWindspeedf > Gear^.dAngle then
+ begin
+ cWindspeedf := cWindspeedf - Gear^.Angle*Steps;
+ if cWindspeedf < Gear^.dAngle then cWindspeedf:= Gear^.dAngle;
+ end
+else if cWindspeedf < Gear^.dAngle then
+ begin
+ cWindspeedf := cWindspeedf + Gear^.Angle*Steps;
+ if cWindspeedf > Gear^.dAngle then cWindspeedf:= Gear^.dAngle;
+ end;
+
+if (WindBarWidth = Gear^.Tag) and (cWindspeedf = Gear^.dAngle) then
+ DeleteVisualGear(Gear)
+end;
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepStraightShot(Gear: PVisualGear; Steps: Longword);
+begin
+Gear^.X:= Gear^.X + Gear^.dX * Steps;
+Gear^.Y:= Gear^.Y - Gear^.dY * Steps;
+
+if Gear^.FrameTicks <= Steps then
+ DeleteVisualGear(Gear)
+else
+ begin
+ dec(Gear^.FrameTicks, Steps);
+ if (Gear^.FrameTicks < 501) and (Gear^.FrameTicks mod 5 = 0) then
+ Gear^.Tint:= (Gear^.Tint and $FFFFFF00) or (((Gear^.Tint and $000000FF) * Gear^.FrameTicks) div 500)
+ end
+end;
+
+
+const handlers: array[TVisualGearType] of TVGearStepProcedure =
+ (
+ @doStepFlake,
+ @doStepCloud,
+ @doStepExpl,
+ @doStepExpl,
+ @doStepFire,
+ @doStepSmallDamage,
+ @doStepTeamHealthSorter,
+ @doStepSpeechBubble,
+ @doStepBubble,
+ @doStepSteam,
+ @doStepAmmo,
+ @doStepSmoke,
+ @doStepSmoke,
+ @doStepShell,
+ @doStepDust,
+ @doStepSplash,
+ @doStepDroplet,
+ @doStepSmokeRing,
+ @doStepBeeTrace,
+ @doStepEgg,
+ @doStepFeather,
+ @doStepHealthTag,
+ @doStepSmokeTrace,
+ @doStepSmokeTrace,
+ @doStepExplosion,
+ @doStepBigExplosion,
+ @doStepChunk,
+ @doStepNote,
+ @doStepLineTrail,
+ @doStepBulletHit,
+ @doStepCircle,
+ @doStepSmoothWindBar,
+ @doStepStraightShot
+ );
+
+procedure initModule;
+begin
+ doStepHandlers:= handlers
+end;
+
+end.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hedgewars/uVisualGearsList.pas Mon Jul 01 23:23:22 2013 +0300
@@ -0,0 +1,462 @@
+(*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *)
+
+{$INCLUDE "options.inc"}
+
+unit uVisualGearsList;
+interface
+uses uTypes;
+
+function AddVisualGear(X, Y: LongInt; Kind: TVisualGearType): PVisualGear; inline;
+function AddVisualGear(X, Y: LongInt; Kind: TVisualGearType; State: LongWord): PVisualGear; inline;
+function AddVisualGear(X, Y: LongInt; Kind: TVisualGearType; State: LongWord; Critical: Boolean): PVisualGear;
+procedure DeleteVisualGear(Gear: PVisualGear);
+function VisualGearByUID(uid : Longword) : PVisualGear;
+
+const
+ cExplFrameTicks = 110;
+
+var VGCounter: LongWord;
+ VisualGearLayers: array[0..6] of PVisualGear;
+
+implementation
+uses uFloat, uVariables, uConsts, uTextures, uVisualGearsHandlers;
+
+function AddVisualGear(X, Y: LongInt; Kind: TVisualGearType): PVisualGear; inline;
+begin
+ AddVisualGear:= AddVisualGear(X, Y, Kind, 0, false);
+end;
+
+function AddVisualGear(X, Y: LongInt; Kind: TVisualGearType; State: LongWord): PVisualGear; inline;
+begin
+ AddVisualGear:= AddVisualGear(X, Y, Kind, State, false);
+end;
+
+function AddVisualGear(X, Y: LongInt; Kind: TVisualGearType; State: LongWord; Critical: Boolean): PVisualGear;
+var gear: PVisualGear;
+ t: Longword;
+ sp: real;
+begin
+AddVisualGear:= nil;
+if ((GameType = gmtSave) or (fastUntilLag and (GameType = gmtNet)) or fastScrolling) and // we are scrolling now
+ ((Kind <> vgtCloud) and (not Critical)) then
+ exit;
+
+if ((cReducedQuality and rqAntiBoom) <> 0) and
+ (not Critical) and
+ (not (Kind in
+ [vgtTeamHealthSorter,
+ vgtSmallDamageTag,
+ vgtSpeechBubble,
+ vgtHealthTag,
+ vgtExplosion,
+ vgtSmokeTrace,
+ vgtEvilTrace,
+ vgtNote,
+ vgtSmoothWindBar])) then
+
+ exit;
+
+inc(VGCounter);
+New(gear);
+FillChar(gear^, sizeof(TVisualGear), 0);
+gear^.X:= real(X);
+gear^.Y:= real(Y);
+gear^.Kind := Kind;
+gear^.doStep:= doStepHandlers[Kind];
+gear^.State:= 0;
+gear^.Tint:= $FFFFFFFF;
+gear^.uid:= VGCounter;
+gear^.Layer:= 0;
+
+with gear^ do
+ case Kind of
+ vgtFlake:
+ begin
+ Timer:= 0;
+ tdX:= 0;
+ tdY:= 0;
+ Scale:= 1.0;
+ if SuddenDeathDmg then
+ begin
+ FrameTicks:= random(vobSDFrameTicks);
+ Frame:= random(vobSDFramesCount);
+ end
+ else
+ begin
+ FrameTicks:= random(vobFrameTicks);
+ Frame:= random(vobFramesCount);
+ end;
+ Angle:= random(360);
+ dx:= 0.0000038654705 * random(10000);
+ dy:= 0.000003506096 * random(7000);
+ if random(2) = 0 then
+ dx := -dx;
+ if SuddenDeathDmg then
+ dAngle:= (random(2) * 2 - 1) * (vobSDVelocity + random(vobSDVelocity)) / 1000
+ else
+ dAngle:= (random(2) * 2 - 1) * (vobVelocity + random(vobVelocity)) / 1000
+ end;
+ vgtCloud:
+ begin
+ Frame:= random(4);
+ dx:= 0.5 + 0.1 * random(5); // how much the cloud will be affected by wind
+ timer:= random(4096);
+ Scale:= 1.0
+ end;
+ vgtExplPart,
+ vgtExplPart2:
+ begin
+ t:= random(1024);
+ sp:= 0.001 * (random(95) + 70);
+ dx:= hwFloat2Float(AngleSin(t)) * sp;
+ dy:= hwFloat2Float(AngleCos(t)) * sp;
+ if random(2) = 0 then
+ dx := -dx;
+ if random(2) = 0 then
+ dy := -dy;
+ Frame:= 7 - random(3);
+ FrameTicks:= cExplFrameTicks
+ end;
+ vgtFire:
+ begin
+ t:= random(1024);
+ sp:= 0.001 * (random(85) + 95);
+ dx:= hwFloat2Float(AngleSin(t)) * sp;
+ dy:= hwFloat2Float(AngleCos(t)) * sp;
+ if random(2) = 0 then
+ dx := -dx;
+ if random(2) = 0 then
+ dy := -dy;
+ FrameTicks:= 650 + random(250);
+ Frame:= random(8)
+ end;
+ vgtEgg:
+ begin
+ t:= random(1024);
+ sp:= 0.001 * (random(85) + 95);
+ dx:= hwFloat2Float(AngleSin(t)) * sp;
+ dy:= hwFloat2Float(AngleCos(t)) * sp;
+ if random(2) = 0 then
+ dx := -dx;
+ if random(2) = 0 then
+ dy := -dy;
+ FrameTicks:= 650 + random(250);
+ Frame:= 1
+ end;
+ vgtShell: FrameTicks:= 500;
+ vgtSmallDamageTag:
+ begin
+ gear^.FrameTicks:= 1100
+ end;
+ vgtBubble:
+ begin
+ dx:= 0.0000038654705 * random(10000);
+ dy:= 0;
+ if random(2) = 0 then
+ dx := -dx;
+ FrameTicks:= 250 + random(1751);
+ Frame:= random(5)
+ end;
+ vgtSteam:
+ begin
+ dx:= 0.0000038654705 * random(10000);
+ dy:= 0.001 * (random(85) + 95);
+ if random(2) = 0 then
+ dx := -dx;
+ Frame:= 7 - random(3);
+ FrameTicks:= cExplFrameTicks * 2;
+ end;
+ vgtAmmo:
+ begin
+ alpha:= 1.0;
+ scale:= 1.0
+ end;
+ vgtSmokeWhite,
+ vgtSmoke:
+ begin
+ Scale:= 1.0;
+ dx:= 0.0002 * (random(45) + 10);
+ dy:= 0.0002 * (random(45) + 10);
+ if random(2) = 0 then
+ dx := -dx;
+ Frame:= 7 - random(2);
+ FrameTicks:= cExplFrameTicks * 2;
+ end;
+ vgtDust:
+ begin
+ dx:= 0.005 * (random(15) + 10);
+ dy:= 0.001 * (random(40) + 20);
+ if random(2) = 0 then dx := -dx;
+ if random(2) = 0 then Tag:= 1
+ else Tag:= -1;
+ Frame:= 7 - random(2);
+ FrameTicks:= random(20) + 15;
+ end;
+ vgtSplash:
+ begin
+ dx:= 0;
+ dy:= 0;
+ FrameTicks:= 740;
+ Frame:= 19;
+ Scale:= 0.75;
+ Timer:= 1;
+ end;
+ vgtDroplet:
+ begin
+ dx:= 0.001 * (random(180) - 90);
+ dy:= -0.001 * (random(160) + 40);
+ FrameTicks:= 250 + random(1751);
+ Frame:= random(3)
+ end;
+ vgtBeeTrace:
+ begin
+ FrameTicks:= 1000;
+ Frame:= random(16);
+ end;
+ vgtSmokeRing:
+ begin
+ dx:= 0;
+ dy:= 0;
+ FrameTicks:= 600;
+ Timer:= 0;
+ Frame:= 0;
+ scale:= 0.6;
+ alpha:= 1;
+ angle:= random(360);
+ end;
+ vgtFeather:
+ begin
+ t:= random(1024);
+ sp:= 0.001 * (random(85) + 95);
+ dx:= hwFloat2Float(AngleSin(t)) * sp;
+ dy:= hwFloat2Float(AngleCos(t)) * sp;
+ if random(2) = 0 then
+ dx := -dx;
+ if random(2) = 0 then
+ dy := -dy;
+ FrameTicks:= 650 + random(250);
+ Frame:= 1
+ end;
+ vgtHealthTag:
+ begin
+ Frame:= 0;
+ Timer:= 1500;
+ dY:= -0.08;
+ dX:= 0;
+ //gear^.Z:= 2002;
+ end;
+ vgtSmokeTrace,
+ vgtEvilTrace:
+ begin
+ gear^.X:= gear^.X - 16;
+ gear^.Y:= gear^.Y - 16;
+ gear^.State:= 8;
+ //gear^.Z:= cSmokeZ
+ end;
+vgtBigExplosion:
+ begin
+ gear^.Angle:= random(360);
+ end;
+ vgtChunk:
+ begin
+ gear^.Frame:= random(4);
+ t:= random(1024);
+ sp:= 0.001 * (random(85) + 47);
+ dx:= hwFloat2Float(AngleSin(t)) * sp;
+ dy:= hwFloat2Float(AngleCos(t)) * sp * -2;
+ if random(2) = 0 then
+ dx := -dx;
+ end;
+ vgtNote:
+ begin
+ dx:= 0.005 * (random(15) + 10);
+ dy:= -0.001 * (random(40) + 20);
+ if random(2) = 0 then
+ dx := -dx;
+ Frame:= random(4);
+ FrameTicks:= random(2000) + 1500;
+ end;
+ vgtBulletHit:
+ begin
+ dx:= 0;
+ dy:= 0;
+ FrameTicks:= 350;
+ Frame:= 7;
+ Angle:= 0;
+ end;
+vgtSmoothWindBar:
+ begin
+ Angle:= hwFloat2Float(cMaxWindSpeed)*2 / 1440; // seems rate below is supposed to change wind bar at 1px per 10ms. Max time, 1440ms. This tries to match the rate of change
+ Tag:= hwRound(cWindSpeed * 72 / cMaxWindSpeed);
+ end;
+ vgtStraightShot:
+ begin
+ Angle:= 0;
+ Scale:= 1.0;
+ dx:= 0.001 * random(45);
+ dy:= 0.001 * (random(20) + 25);
+ State:= ord(sprHealth);
+ if random(2) = 0 then
+ dx := -dx;
+ Frame:= 0;
+ FrameTicks:= random(750) + 1250;
+ State:= ord(sprSnowDust);
+ end;
+ end;
+
+if State <> 0 then
+ gear^.State:= State;
+
+case Gear^.Kind of
+ vgtFlake: if cFlattenFlakes then
+ gear^.Layer:= 0
+ else if random(3) = 0 then
+ begin
+ gear^.Scale:= 0.5;
+ gear^.Layer:= 0 // 33% - far back
+ end
+ else if random(3) = 0 then
+ begin
+ gear^.Scale:= 0.8;
+ gear^.Layer:= 4 // 22% - mid-distance
+ end
+ else if random(3) <> 0 then
+ gear^.Layer:= 5 // 30% - just behind land
+ else if random(2) = 0 then
+ gear^.Layer:= 6 // 7% - just in front of land
+ else
+ begin
+ gear^.Scale:= 1.5;
+ gear^.Layer:= 2; // 7% - close up
+ end;
+
+ vgtCloud: if cFlattenClouds then gear^.Layer:= 5
+ else if random(3) = 0 then
+ begin
+ gear^.Scale:= 0.25;
+ gear^.Layer:= 0
+ end
+ else if random(2) = 0 then
+ gear^.Layer:= 5
+ else
+ begin
+ gear^.Scale:= 0.4;
+ gear^.Layer:= 4
+ end;
+
+ // 0: this layer is very distant in the background when in stereo
+ vgtTeamHealthSorter,
+ vgtSmoothWindBar: gear^.Layer:= 0;
+
+
+ // 1: this layer is on the land level (which is close but behind the screen plane) when stereo
+ vgtSmokeTrace,
+ vgtEvilTrace,
+ vgtLineTrail,
+ vgtSmoke,
+ vgtSmokeWhite,
+ vgtDust,
+ vgtFire,
+ vgtSplash,
+ vgtDroplet,
+ vgtBubble: gear^.Layer:= 1;
+
+ // 3: this layer is on the screen plane (depth = 0) when stereo
+ vgtSpeechBubble,
+ vgtSmallDamageTag,
+ vgtHealthTag,
+ vgtStraightShot,
+ vgtChunk: gear^.Layer:= 3;
+
+ // 2: this layer is outside the screen when stereo
+ vgtExplosion,
+ vgtBigExplosion,
+ vgtExplPart,
+ vgtExplPart2,
+ vgtSteam,
+ vgtAmmo,
+ vgtShell,
+ vgtFeather,
+ vgtEgg,
+ vgtBeeTrace,
+ vgtSmokeRing,
+ vgtNote,
+ vgtBulletHit,
+ vgtCircle: gear^.Layer:= 2
+end;
+
+if VisualGearLayers[gear^.Layer] <> nil then
+ begin
+ VisualGearLayers[gear^.Layer]^.PrevGear:= gear;
+ gear^.NextGear:= VisualGearLayers[gear^.Layer]
+ end;
+VisualGearLayers[gear^.Layer]:= gear;
+
+AddVisualGear:= gear;
+end;
+
+procedure DeleteVisualGear(Gear: PVisualGear);
+begin
+ FreeTexture(Gear^.Tex);
+ Gear^.Tex:= nil;
+
+ if Gear^.NextGear <> nil then
+ Gear^.NextGear^.PrevGear:= Gear^.PrevGear;
+ if Gear^.PrevGear <> nil then
+ Gear^.PrevGear^.NextGear:= Gear^.NextGear
+ else
+ VisualGearLayers[Gear^.Layer]:= Gear^.NextGear;
+
+ if lastVisualGearByUID = Gear then
+ lastVisualGearByUID:= nil;
+
+ Dispose(Gear);
+end;
+
+function VisualGearByUID(uid : Longword) : PVisualGear;
+var vg: PVisualGear;
+ i: LongWord;
+begin
+VisualGearByUID:= nil;
+if uid = 0 then
+ exit;
+if (lastVisualGearByUID <> nil) and (lastVisualGearByUID^.uid = uid) then
+ begin
+ VisualGearByUID:= lastVisualGearByUID;
+ exit
+ end;
+// search in an order that is more likely to return layers they actually use. Could perhaps track statistically AddVisualGear in uScript, since that is most likely the ones they want
+for i:= 2 to 5 do
+ begin
+ vg:= VisualGearLayers[i mod 4];
+ while vg <> nil do
+ begin
+ if vg^.uid = uid then
+ begin
+ lastVisualGearByUID:= vg;
+ VisualGearByUID:= vg;
+ exit
+ end;
+ vg:= vg^.NextGear
+ end
+ end
+end;
+
+
+end.
--- a/share/hedgewars/Data/Locale/campaigns_en.txt Mon Jul 01 22:28:42 2013 +0300
+++ b/share/hedgewars/Data/Locale/campaigns_en.txt Mon Jul 01 23:23:22 2013 +0300
@@ -1,23 +1,25 @@
-A Classic Fairytale-first_blood.desc="Help Leaks a lot to complete his training and become a proper hedgehog warrior. You will be trained in the art of rope, parachute, shoryuken and desert eagle."
+A_Classic_Fairytale-first_blood.desc="Help Leaks a lot to complete his training and become a proper hedgehog warrior. You will be trained in the art of rope, parachute, shoryuken and desert eagle."
-A Classic Fairytale-shadow.desc="Leaks a lot and Dense Cloud are going for hunting. Be prepared for the dangers awaiting you at the forest. Remember, make your choices wisely."
+A_Classic_Fairytale-shadow.desc="Leaks a lot and Dense Cloud are going for hunting. Be prepared for the dangers awaiting you at the forest. Remember, make your choices wisely."
-A Classic Fairytale-journey.desc="Leaks a lot has to go to the other side of the island. Be fast and cautious."
+A_Classic_Fairytale-journey.desc="Leaks a lot has to go to the other side of the island. Be fast and cautious."
-A Classic Fairytale-united.desc="After his long journey Leaks a lot is finally back to the village. However, there isn't time to rest. You have to defend the village from the rage of the cannibals."
+A_Classic_Fairytale-united.desc="After his long journey Leaks a lot is finally back to the village. However, there isn't time to rest. You have to defend the village from the rage of the cannibals."
-A Classic Fairytale-backstab.desc="The monstrous cannibals are hunting Leaks a lot and his friends. Defeat them once again and protect your allies. Use your resources accordingly to defeat the incoming enemies!"
+A_Classic_Fairytale-backstab.desc="The monstrous cannibals are hunting Leaks a lot and his friends. Defeat them once again and protect your allies. Use your resources accordingly to defeat the incoming enemies!"
-A Classic Fairytale-dragon.desc="Leaks a lot has to get to the other side of the lake. Become a rope master and avoid get hit by the enemy shots."
+A_Classic_Fairytale-dragon.desc="Leaks a lot has to get to the other side of the lake. Become a rope master and avoid get hit by the enemy shots."
-A Classic Fairytale-family.desc="Leaks a lot has to save once more his allies. Eliminate the enemy hogs and free your comrades. Use your resources carefully as they are limited. Drill some holes in the right spot and go close to the princess."
+A_Classic_Fairytale-family.desc="Leaks a lot has to save once more his allies. Eliminate the enemy hogs and free your comrades. Use your resources carefully as they are limited. Drill some holes in the right spot and go close to the princess."
-A Classic Fairytale-queen.desc="Leaks a lot has to fight once again. In order to win he'll have to fight the traitor and use all the resources available. Defeat the enemy!"
+A_Classic_Fairytale-queen.desc="Leaks a lot has to fight once again. In order to win he'll have to fight the traitor and use all the resources available. Defeat the enemy!"
-A Classic Fairytale-enemy.desc="What a great twist! Leaks a lot has to fight side by side with the… “cannibals” against the common enemy. The evil cyborgs!"
+A_Classic_Fairytale-enemy.desc="What a great twist! Leaks a lot has to fight side by side with the… “cannibals” against the common enemy. The evil cyborgs!"
-A Classic Fairytale-epil.desc="Congratulations! Leaks a lot can finally leave in peace and get praised by his new friends and his tribe. Be proud for what you succeed! You can play again previous missions and see the other possible endings."
+A_Classic_Fairytale-epil.desc="Congratulations! Leaks a lot can finally leave in peace and get praised by his new friends and his tribe. Be proud for what you succeed! You can play again previous missions and see the other possible endings."
-A Space Adventure-cosmos.desc="Hogera, the planet of hogs is about to be hit by a gigantic meteorite. In this race for survival you have to lead PAoTH's best pilot, Hog Solo, in a space trip around the neighbor planets to collect all the 4 pieces of the long lost anti gravity device!"
-A Space Adventure-moon01.desc="MOON TEST"
-A Space Adventure-ice.desc="ICE TEST"
+A_Space_Adventure-cosmos.desc="Hogera, the planet of hogs is about to be hit by a gigantic meteorite. In this race for survival you have to lead PAoTH's best pilot, Hog Solo, in a space trip around the neighbor planets to collect all the 4 pieces of the long lost anti gravity device!"
+A_Space_Adventure-moon01.desc="MOON TEST"
+A_Space_Adventure-ice.desc="ICE TEST"
+
+
--- a/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/CMakeLists.txt Mon Jul 01 22:28:42 2013 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-file(GLOB Config *.ini)
-file(GLOB Missions *.lua)
-file(GLOB Packs *.hwp)
-
-install(FILES
- ${Config}
- ${Missions}
- ${Packs}
- DESTINATION "${SHAREPATH}Data/Missions/Campaign/A Classic Fairytale")
--- a/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/backstab.lua Mon Jul 01 22:28:42 2013 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1101 +0,0 @@
-HedgewarsScriptLoad("/Scripts/Locale.lua")
-HedgewarsScriptLoad("/Scripts/Animate.lua")
-
------------------------------Constants---------------------------------
-choiceAccepted = 1
-choiceRefused = 2
-choiceAttacked = 3
-
-choiceEliminate = 1
-choiceSpare = 2
-
-leaksNum = 1
-denseNum = 2
-waterNum = 3
-buffaloNum = 4
-chiefNum = 5
-girlNum = 6
-wiseNum = 7
-
-spyKillStage = 1
-platformStage = 2
-wave3Stage = 3
-
-tmpVar = 0
-
-nativeNames = {loc("Leaks A Lot"), loc("Dense Cloud"), loc("Fiery Water"),
- loc("Raging Buffalo"), loc("Righteous Beard"), loc("Fell From Grace"),
- loc("Wise Oak"), loc("Eagle Eye"), loc("Flaming Worm")}
-
-nativeHats = {"Rambo", "RobinHood", "pirate_jack", "zoo_Bunny", "IndianChief",
- "tiara", "AkuAku", "None", "None"}
-
-nativePos = {{887, 329}, {1050, 288}, {1731, 707},
- {830, 342}, {1001, 290}, {773, 340},
- {953, 305}, {347, 648}, {314, 647}}
-
-nativeDir = {"Right", "Left", "Left",
- "Right", "Left", "Right",
- "Left", "Right", "Right"}
-
-cannibalNames = {loc("Brain Teaser"), loc("Bone Jackson"), loc("Gimme Bones"),
- loc("Hedgibal Lecter"), loc("Bloodpie"), loc("Scalp Muncher"),
- loc("Back Breaker"), loc("Dahmer"), loc("Meiwes"),
- loc("Ear Sniffer"), loc("Regurgitator"), loc("Muriel")}
-
-cannibalPos = {{3607, 1472}, {3612, 1487}, {3646, 1502},
- {3507, 195}, {3612, 1487}, {840, 1757},
- {3056, 1231}, {2981, 1222}, {2785, 1258}}
-
-cannibalDir = {"Left", "Left", "Left",
- "Left", "Right", "Right",
- "Left", "Left", "Left"}
-
-cyborgPos = {1369, 574}
-cyborgPos2 = {1308, 148}
-
-deployedPos = {2522, 1365}
------------------------------Variables---------------------------------
-natives = {}
-nativeDead = {}
-nativeHidden = {}
-nativeRevived = {}
-nativesNum = 0
-
-cannibals = {}
-cannibalDead = {}
-cannibalHidden = {}
-
-speakerHog = nil
-spyHog = nil
-deployedHog = nil
-deployedDead = false
-
-cyborgHidden = false
-needToAct = 0
-
-m2Choice = 0
-m2DenseDead = 0
-m4DenseDead = 0
-m4BuffaloDead = 0
-m4WaterDead = 0
-m4ChiefDead = 0
-m4LeaksDead = 0
-
-needRevival = false
-gearr = nil
-startElimination = 0
-stage = 0
-choice = 0
-highJumped = false
-TurnsLeft = 0
-startNativesNum = 0
-
-startAnim = {}
-afterChoiceAnim = {}
-wave2Anim = {}
-wave2DeadAnim = {}
-wave3DeadAnim = {}
-
-vCircs = {}
------------------------------Animations--------------------------------
-function Wave2Reaction()
- local i = 1
- local gearr = nil
- while nativeDead[i] == true do
- i = i + 1
- end
- gearr = natives[i]
- if nativeDead[denseNum] ~= true and band(GetState(natives[denseNum]), gstDrowning) == 0 then
- AnimInsertStepNext({func = AnimCustomFunction, args = {dense, EmitDenseClouds, {"Left"}}})
- AnimInsertStepNext({func = AnimTurn, args = {dense, "Left"}})
- end
- if nativeDead[buffaloNum] ~= true and band(GetState(natives[buffaloNum]), gstDrowning) == 0 then
- AnimInsertStepNext({func = AnimSay, args = {natives[buffaloNum], loc("Let them have a taste of my fury!"), SAY_SHOUT, 6000}})
- end
- AnimInsertStepNext({func = AnimSay, args = {gearr, loc("There's more of them? When did they become so hungry?"), SAY_SHOUT, 8000}})
-end
-
-function EmitDenseClouds(dir)
- local dif
- if dir == "Left" then
- dif = 10
- else
- dif = -10
- end
- AnimInsertStepNext({func = AnimVisualGear, args = {natives[denseNum], GetX(natives[denseNum]) + dif, GetY(natives[denseNum]) + dif, vgtSteam, 0, true}, swh = false})
- AnimInsertStepNext({func = AnimVisualGear, args = {natives[denseNum], GetX(natives[denseNum]) + dif, GetY(natives[denseNum]) + dif, vgtSteam, 0, true}, swh = false})
- AnimInsertStepNext({func = AnimVisualGear, args = {natives[denseNum], GetX(natives[denseNum]) + dif, GetY(natives[denseNum]) + dif, vgtSteam, 0, true}, swh = false})
- AnimInsertStepNext({func = AnimWait, args = {natives[denseNum], 800}})
- AnimInsertStepNext({func = AnimVisualGear, args = {natives[denseNum], GetX(natives[denseNum]) + dif, GetY(natives[denseNum]) + dif, vgtSteam, 0, true}, swh = false})
- AnimInsertStepNext({func = AnimVisualGear, args = {natives[denseNum], GetX(natives[denseNum]) + dif, GetY(natives[denseNum]) + dif, vgtSteam, 0, true}, swh = false})
- AnimInsertStepNext({func = AnimWait, args = {natives[denseNum], 800}})
- AnimInsertStepNext({func = AnimVisualGear, args = {natives[denseNum], GetX(natives[denseNum]) + dif, GetY(natives[denseNum]) + dif, vgtSteam, 0, true}, swh = false})
-end
-
-function SaySafe()
- local i = 1
- while gearr == nil do
- if nativeDead[i] ~= true and nativeHidden[i] ~= true then
- gearr = natives[i]
- end
- i = i + 1
- end
- AnimInsertStepNext({func = AnimSay, args = {natives[wiseNum], loc("We are indeed."), SAY_SAY, 2500}})
- AnimInsertStepNext({func = AnimSay, args = {gearr, loc("I think we are safe here."), SAY_SAY, 4000}})
-end
-
-function ReviveNatives()
- for i = 1, 7 do
- if nativeHidden[i] == true and nativeDead[i] ~= true then
- RestoreHog(natives[i])
- nativeHidden[i] = false
- nativeRevived[i] = true
- AnimInsertStepNext({func = AnimOutOfNowhere, args = {natives[i], unpack(nativePos[i])}})
- end
- end
-end
-
-function WonderAlive()
- if nativeRevived[waterNum] == true then
- AnimInsertStepNext({func = AnimSay, args = {natives[waterNum], loc("I'm...alive? How? Why?"), SAY_THINK, 3500}})
- AnimInsertStepNext({func = AnimWait, args = {natives[waterNum], 800}})
- AnimInsertStepNext({func = AnimTurn, args = {natives[waterNum], "Left"}})
- AnimInsertStepNext({func = AnimWait, args = {natives[waterNum], 800}})
- AnimInsertStepNext({func = AnimTurn, args = {natives[waterNum], "Right"}})
- end
- if nativeRevived[leaksNum] == true and nativeRevived[denseNum] == true then
- AnimInsertStepNext({func = AnimSay, args = {natives[leaksNum], loc("But why would they help us?"), SAY_SAY, 4000}})
- AnimInsertStepNext({func = AnimSay, args = {natives[leaksNum], loc("It must be the aliens!"), SAY_SAY, 3500}})
- AnimInsertStepNext({func = AnimSay, args = {natives[girlNum], loc("You just appeared out of thin air!"), SAY_SAY, 5000}})
- AnimInsertStepNext({func = AnimSay, args = {natives[leaksNum], loc("But...we died!"), SAY_SAY, 2500}})
- AnimInsertStepNext({func = AnimSay, args = {natives[leaksNum], loc("This must be the caves!"), SAY_SAY, 3500}})
- AnimInsertStepNext({func = AnimSay, args = {natives[denseNum], loc("Dude, where are we?"), SAY_SAY, 3000}})
- AnimInsertStepNext({func = AnimWait, args = {natives[leaksNum], 800}})
- AnimInsertStepNext({func = AnimTurn, args = {natives[leaksNum], "Right"}})
- AnimInsertStepNext({func = AnimTurn, args = {natives[denseNum], "Left"}})
- AnimInsertStepNext({func = AnimWait, args = {natives[leaksNum], 800}})
- AnimInsertStepNext({func = AnimTurn, args = {natives[leaksNum], "Left"}})
- AnimInsertStepNext({func = AnimTurn, args = {natives[denseNum], "Right"}})
- AnimInsertStepNext({func = AnimWait, args = {natives[leaksNum], 800}})
- AnimInsertStepNext({func = AnimTurn, args = {natives[leaksNum], "Right"}})
- AnimInsertStepNext({func = AnimTurn, args = {natives[denseNum], "Left"}})
- AnimInsertStepNext({func = AnimWait, args = {natives[leaksNum], 800}})
- AnimInsertStepNext({func = AnimTurn, args = {natives[leaksNum], "Left"}})
- AnimInsertStepNext({func = AnimTurn, args = {natives[denseNum], "Right"}})
- AnimInsertStepNext({func = AnimCustomFunction, swh = false, args = {natives[leaksNum], CondNeedToTurn, {natives[leaksNum], natives[girlNum]}}})
- if nativeDead[chiefNum] ~= true then
- AnimInsertStepNext({func = AnimTurn, args = {natives[chiefNum], "Right"}})
- end
- elseif nativeRevived[leaksNum] == true then
- AnimInsertStepNext({func = AnimSay, args = {natives[leaksNum], loc("Why would they do this?"), SAY_SAY, 6000}})
- AnimInsertStepNext({func = AnimSay, args = {natives[wiseNum], loc("It must be the aliens' deed."), SAY_SAY, 5000}})
- AnimInsertStepNext({func = AnimSay, args = {natives[wiseNum], loc("Do not laugh, inexperienced one, for he speaks the truth!"), SAY_SAY, 10000}})
- AnimInsertStepNext({func = AnimSay, args = {natives[leaksNum], loc("Yeah, sure! I died. Hillarious!"), SAY_SAY, 6000}})
- AnimInsertStepNext({func = AnimSay, args = {gearr, loc("You're...alive!? But we saw you die!"), SAY_SAY, 6000}})
- AnimInsertStepNext({func = AnimSay, args = {gearr, loc("???"), SAY_SAY, 2000}})
- AnimInsertStepNext({func = AnimSay, args = {natives[leaksNum], loc("Wow, what a dream!"), SAY_SAY, 3000}})
- if nativeDead[chiefNum] ~= true then
- AnimInsertStepNext({func = AnimTurn, args = {natives[chiefNum], "Right"}})
- end
- AnimInsertStepNext({func = AnimCustomFunction, swh = false, args = {natives[leaksNum], CondNeedToTurn, {natives[leaksNum], natives[wiseNum]}}})
- AnimInsertStepNext({func = AnimCustomFunction, swh = false, args = {natives[leaksNum], CondNeedToTurn, {natives[leaksNum], gearr}}})
- elseif nativeRevived[denseNum] == true then
- AnimInsertStepNext({func = AnimSay, args = {natives[denseNum], loc("Dude, that's so cool!"), SAY_SAY, 3000}})
- AnimInsertStepNext({func = AnimSay, args = {natives[wiseNum], loc("It must be the aliens' deed."), SAY_SAY, 5000}})
- AnimInsertStepNext({func = AnimSay, args = {natives[denseNum], loc("But that's impossible!"), SAY_SAY, 3000}})
- AnimInsertStepNext({func = AnimSay, args = {natives[wiseNum], loc("It was not a dream, unwise one!"), SAY_SAY, 5000}})
- AnimInsertStepNext({func = AnimSay, args = {natives[denseNum], loc("Exactly, man! That was my dream."), SAY_SAY, 5000}})
- AnimInsertStepNext({func = AnimSay, args = {gearr, loc("You're...alive!? But we saw you die!"), SAY_SAY, 6000}})
- AnimInsertStepNext({func = AnimSay, args = {gearr, loc("???"), SAY_SAY, 2000}})
- AnimInsertStepNext({func = AnimSay, args = {natives[denseNum], loc("Dude, wow! I just had the weirdest high!"), SAY_SAY, 6000}})
- if nativeDead[chiefNum] ~= true then
- AnimInsertStepNext({func = AnimTurn, args = {natives[chiefNum], "Right"}})
- end
- AnimInsertStepNext({func = AnimCustomFunction, swh = false, args = {natives[denseNum], CondNeedToTurn, {natives[denseNum], natives[wiseNum]}}})
- AnimInsertStepNext({func = AnimCustomFunction, swh = false, args = {natives[denseNum], CondNeedToTurn, {natives[denseNum], gearr}}})
- end
-end
-
-function ExplainAlive()
- if needRevival == true and m4WaterDead == 1 then
- RestoreCyborg()
- AnimSetGearPosition(cyborg, unpack(cyborgPos))
- AnimInsertStepNext({func = AnimCustomFunction, args = {water, HideCyborg, {}}})
- AnimInsertStepNext({func = AnimSwitchHog, args = {water}})
- AnimInsertStepNext({func = AnimSay, args = {cyborg, loc("The answer is...entertaintment. You'll see what I mean."), SAY_SAY, 8000}})
- AnimInsertStepNext({func = AnimSay, args = {cyborg, loc("You're probably wondering why I bought you back..."), SAY_SAY, 8000}})
- end
-end
-
-function SpyDebate()
- if m2Choice == choiceAccepted then
- spyHog = natives[denseNum]
- AnimInsertStepNext({func = AnimSay, args = {natives[wiseNum], loc("What shall we do with the traitor?"), SAY_SAY, 6000}})
- AnimInsertStepNext({func = SetHealth, swh = false, args = {natives[denseNum], 26}})
- AnimInsertStepNext({func = AnimVisualGear, args = {natives[wiseNum], GetGearPosition(natives[denseNum]), vgtExplosion, 0, true}})
- AnimInsertStepNext({func = AnimSay, args = {natives[wiseNum], loc("Here, let me help you!"), SAY_SAY, 3000}})
- if nativeDead[chiefNum] == true then
- AnimInsertStepNext({func = AnimSay, args = {natives[leaksNum], loc("I forgot that she's the daughter of the chief, too..."), SAY_THINK, 7000}})
- AnimInsertStepNext({func = AnimSay, args = {natives[girlNum], loc("You killed my father, you monster!"), SAY_SAY, 5000}})
- end
- AnimInsertStepNext({func = AnimSay, args = {natives[denseNum], loc("Look, I had no choice!"), SAY_SAY, 3000}})
- AnimInsertStepNext({func = AnimSay, args = {natives[leaksNum], loc("You have been giving us out to the enemy, haven't you!"), SAY_SAY, 7000}})
- AnimInsertStepNext({func = AnimSay, args = {natives[leaksNum], loc("You're a pathetic liar!"), SAY_SAY, 3000}})
- AnimInsertStepNext({func = AnimSay, args = {natives[leaksNum], loc("Interesting! Last time you said you killed a cannibal!"), SAY_SAY, 7000}})
- AnimInsertStepNext({func = AnimSay, args = {natives[denseNum], loc("I told you, I just found them."), SAY_SAY, 4500}})
- AnimInsertStepNext({func = AnimCustomFunction, args = {natives[denseNum], EmitDenseClouds, {"Left"}}})
- AnimInsertStepNext({func = AnimSay, args = {natives[leaksNum], loc("Where did you get the weapons in the forest, Dense Cloud?"), SAY_SAY, 8000}})
- AnimInsertStepNext({func = AnimSay, args = {natives[leaksNum], loc("Not now, Fiery Water!"), SAY_SAY, 3000}})
- else
- spyHog = natives[waterNum]
- AnimInsertStepNext({func = AnimSay, args = {natives[wiseNum], loc("What shall we do with the traitor?"), SAY_SAY, 5000}})
- AnimInsertStepNext({func = SetHealth, swh = false, args = {natives[waterNum], 26}})
- AnimInsertStepNext({func = AnimVisualGear, args = {natives[wiseNum], nativePos[denseNum][1] + 50, nativePos[denseNum][2], vgtExplosion, 0, true}})
- AnimInsertStepNext({func = AnimSay, args = {natives[girlNum], loc("I can't believe what I'm hearing!"), SAY_SAY, 5500}})
- AnimInsertStepNext({func = AnimSay, args = {natives[waterNum], loc("You know what? I don't even regret anything!"), SAY_SAY, 7000}})
- AnimInsertStepNext({func = AnimSay, args = {natives[girlNum], loc("In fact, you are the only one that's been acting strangely."), SAY_SAY, 8000}})
- AnimInsertStepNext({func = AnimSay, args = {natives[waterNum], loc("Are you accusing me of something?"), SAY_SAY, 3500}})
- AnimInsertStepNext({func = AnimSay, args = {natives[leaksNum], loc("Seems like every time you take a \"walk\", the enemy find us!"), SAY_SAY, 8000}})
- AnimInsertStepNext({func = AnimSay, args = {natives[waterNum], loc("You know...taking a stroll."), SAY_SAY, 3500}})
- AnimInsertStepNext({func = AnimSay, args = {natives[leaksNum], loc("Where have you been?!"), SAY_SAY, 3000}})
- end
- if nativeRevived[waterNum] == true then
- AnimInsertStepNext({func = AnimSay, args = {natives[waterNum], loc("You won't believe what happened to me!"), SAY_SAY, 5500}})
- end
- AnimInsertStepNext({func = AnimSay, args = {natives[waterNum], loc("Hey, guys!"), SAY_SAY, 2000}})
- AnimInsertStepNext({func = AnimMove, args = {natives[waterNum], "Left", nativePos[denseNum][1] + 50, nativePos[denseNum][2]}})
- AnimInsertStepNext({func = AnimJump, args = {natives[waterNum], "back"}})
- AnimInsertStepNext({func = AnimTurn, args = {natives[waterNum], "Right"}})
- AnimInsertStepNext({func = AnimMove, args = {natives[waterNum], "Left", 1228, 412}})
- AnimInsertStepNext({func = AnimJump, args = {natives[waterNum], "long"}})
- AnimInsertStepNext({func = AnimJump, args = {natives[waterNum], "long"}})
- AnimInsertStepNext({func = AnimJump, args = {natives[waterNum], "long"}})
- AnimInsertStepNext({func = AnimTurn, args = {natives[waterNum], "Left"}})
- AnimInsertStepNext({func = AnimSay, args = {natives[wiseNum], loc("There must be a spy among us!"), SAY_SAY, 4000}})
- AnimInsertStepNext({func = AnimSay, args = {natives[girlNum], loc("We made sure noone followed us!"), SAY_SAY, 4000}})
- AnimInsertStepNext({func = AnimSay, args = {natives[leaksNum], loc("What? Here? How did they find us?!"), SAY_SAY, 5000}})
-end
-
-function AnimationSetup()
- table.insert(startAnim, {func = AnimWait, swh = false, args = {natives[leaksNum], 3000}})
- table.insert(startAnim, {func = AnimCustomFunction, swh = false, args = {natives[leaksNum], SaySafe, {}}})
- if needRevival == true then
- table.insert(startAnim, {func = AnimCustomFunction, swh = false, args = {cyborg, ReviveNatives, {}}})
- table.insert(startAnim, {func = AnimCustomFunction, swh = false, args = {natives[leaksNum], WonderAlive, {}}})
- table.insert(startAnim, {func = AnimCustomFunction, swh = false, args = {cyborg, ExplainAlive, {}}})
- end
- table.insert(startAnim, {func = AnimCustomFunction, swh = false, args = {natives[leaksNum], RestoreWave, {1}}})
- table.insert(startAnim, {func = AnimOutOfNowhere, args = {cannibals[1], unpack(cannibalPos[1])}})
- table.insert(startAnim, {func = AnimOutOfNowhere, args = {cannibals[2], unpack(cannibalPos[2])}})
- table.insert(startAnim, {func = AnimOutOfNowhere, args = {cannibals[3], unpack(cannibalPos[3])}})
- table.insert(startAnim, {func = AnimWait, args = {natives[leaksNum], 1000}})
- table.insert(startAnim, {func = AnimCustomFunction, swh = false, args = {natives[leaksNum], SpyDebate, {}}})
- AddSkipFunction(startAnim, SkipStartAnim, {})
-end
-
-function SetupWave2Anim()
- for i = 7, 1, -1 do
- if nativeDead[i] ~= true then
- speakerHog = natives[i]
- end
- end
- table.insert(wave2Anim, {func = AnimOutOfNowhere, args = {cannibals[4], unpack(cannibalPos[4])}})
- table.insert(wave2Anim, {func = AnimOutOfNowhere, args = {cannibals[5], unpack(cannibalPos[5])}})
- table.insert(wave2Anim, {func = AnimOutOfNowhere, args = {cannibals[6], unpack(cannibalPos[6])}})
- table.insert(wave2Anim, {func = AnimSay, args = {speakerHog, loc("Look out! There's more of them!"), SAY_SHOUT, 5000}})
- AddSkipFunction(wave2Anim, SkipWave2Anim, {})
-end
-
-function PutCircles()
- if circlesPut then
- return
- end
- vCircs[1] = AddVisualGear(0,0,vgtCircle,0,true)
- vCircs[2] = AddVisualGear(0,0,vgtCircle,0,true)
- vCircs[3] = AddVisualGear(0,0,vgtCircle,0,true)
- SetVisualGearValues(vCircs[1], cannibalPos[7][1], cannibalPos[7][2], 100, 255, 1, 10, 0, 120, 3, 0xff00ffff)
- SetVisualGearValues(vCircs[2], cannibalPos[8][1], cannibalPos[8][2], 100, 255, 1, 10, 0, 120, 3, 0xff00ffff)
- SetVisualGearValues(vCircs[3], cannibalPos[9][1], cannibalPos[9][2], 100, 255, 1, 10, 0, 120, 3, 0xff00ffff)
- circlesPut = true
-end
-
-function SetupWave2DeadAnim()
- for i = 7, 1, -1 do
- if nativeDead[i] ~= true then
- deployedHog = natives[i]
- end
- end
- if nativeDead[wiseNum] ~= true and band(GetState(natives[wiseNum]), gstDrowning) == 0 then
- if nativesNum > 1 then
- table.insert(wave2DeadAnim, {func = AnimWait, args = {natives[wiseNum], 1500}})
- table.insert(wave2DeadAnim, {func = AnimSay, args = {natives[wiseNum], loc("What a strange feeling!"), SAY_THINK, 3000}})
- table.insert(wave2DeadAnim, {func = AnimSay, args = {natives[wiseNum], loc("I need to warn the others."), SAY_THINK, 3000}})
- table.insert(wave2DeadAnim, {func = AnimSay, args = {natives[wiseNum], loc("If only I had a way..."), SAY_THINK, 3000}})
- table.insert(wave2DeadAnim, {func = AnimSay, args = {natives[wiseNum], loc("Oh, silly me! I forgot that I'm the shaman."), SAY_THINK, 6000}})
- table.insert(wave2DeadAnim, {func = AnimCustomFunction, args = {natives[wiseNum], TeleportNatives, {}}})
- table.insert(wave2DeadAnim, {func = AnimCustomFunction, args = {natives[wiseNum], TurnNatives, {natives[wiseNum]}}})
- table.insert(wave2DeadAnim, {func = AnimCustomFunction, args = {natives[wiseNum], CondNeedToTurn, {natives[wiseNum], deployedHog}}})
- table.insert(wave2DeadAnim, {func = AnimSay, args = {natives[wiseNum], loc("I sense another wave of cannibals heading our way!"), SAY_SAY, 6500}})
- table.insert(wave2DeadAnim, {func = AnimSay, args = {natives[wiseNum], loc("I feel something...a place! They will arrive near the circles!"), SAY_SAY, 7500}})
- table.insert(wave2DeadAnim, {func = AnimCustomFunction, args = {natives[wiseNum], PutCircles, {}}})
- table.insert(wave2DeadAnim, {func = AnimFollowGear, swh = false, args = {vCircs[1]}})
- table.insert(wave2DeadAnim, {func = AnimWait, args = {natives[wiseNum], 1500}})
- table.insert(wave2DeadAnim, {func = AnimSay, args = {natives[wiseNum], loc("We need to prevent their arrival!"), SAY_SAY, 4500}})
- table.insert(wave2DeadAnim, {func = AnimSay, args = {natives[wiseNum], loc("Go, quick!"), SAY_SAY, 2500}})
- table.insert(wave2DeadAnim, {func = AnimCustomFunction, args = {natives[wiseNum], DeployHog, {}}})
- table.insert(wave2DeadAnim, {func = AnimCustomFunction, args = {natives[wiseNum], RestoreCyborg, {}}})
- table.insert(wave2DeadAnim, {func = AnimOutOfNowhere, swh = false, args = {cyborg, cyborgPos2[1], cyborgPos2[2]}})
- table.insert(wave2DeadAnim, {func = AnimTurn, args = {cyborg, "Left"}})
- table.insert(wave2DeadAnim, {func = AnimCustomFunction, args = {cyborg, IsolateNatives, {}}})
- table.insert(wave2DeadAnim, {func = AnimCustomFunction, args = {cyborg, PutCGI, {}}})
- table.insert(wave2DeadAnim, {func = AnimSay, args = {cyborg, loc("I want to see how it handles this!"), SAY_SAY, 6000}})
- table.insert(wave2DeadAnim, {func = AnimSwitchHog, args = {deployedHog}})
- table.insert(wave2DeadAnim, {func = AnimDisappear, args = {cyborg, 0, 0}})
--- table.insert(wave2DeadAnim, {func = AnimCustomFunction, args = {cyborg, DeployHog, {}}})
- table.insert(wave2DeadAnim, {func = AnimCustomFunction, swh = false, args = {cyborg, HideCyborg, {}}})
- else
- table.insert(wave2DeadAnim, {func = AnimWait, args = {natives[wiseNum], 1500}})
- table.insert(wave2DeadAnim, {func = AnimSay, args = {natives[wiseNum], loc("What a strange feeling!"), SAY_THINK, 3000}})
- table.insert(wave2DeadAnim, {func = AnimSay, args = {natives[wiseNum], loc("I sense another wave of cannibals heading my way!"), SAY_THINK, 6500}})
- table.insert(wave2DeadAnim, {func = AnimSay, args = {natives[wiseNum], loc("I feel something...a place! They will arrive near the circles!"), SAY_SAY, 7500}})
- table.insert(wave2DeadAnim, {func = AnimCustomFunction, args = {natives[wiseNum], PutCircles, {}}})
- table.insert(wave2DeadAnim, {func = AnimFollowGear, swh = false, args = {vCircs[1]}})
- table.insert(wave2DeadAnim, {func = AnimSay, args = {natives[wiseNum], loc("I need to prevent their arrival!"), SAY_THINK, 4500}})
- table.insert(wave2DeadAnim, {func = AnimSay, args = {natives[wiseNum], loc("If only I had a way..."), SAY_THINK, 3000}})
- table.insert(wave2DeadAnim, {func = AnimSay, args = {natives[wiseNum], loc("Oh, silly me! I forgot that I'm the shaman."), SAY_THINK, 6000}})
- end
- else
- table.insert(wave2DeadAnim, {func = AnimWait, args = {cyborg, 1500}})
- table.insert(wave2DeadAnim, {func = AnimCustomFunction, swh = false, args = {cyborg, RestoreCyborg, {}}})
- table.insert(wave2DeadAnim, {func = AnimOutOfNowhere, args = {cyborg, cyborgPos2[1], cyborgPos2[2]}})
- table.insert(wave2DeadAnim, {func = AnimTurn, args = {cyborg, "Left"}})
- table.insert(wave2DeadAnim, {func = AnimCustomFunction, args = {cyborg, TeleportNatives, {}}})
- table.insert(wave2DeadAnim, {func = AnimCustomFunction, args = {cyborg, TurnNatives, {cyborg}}})
- table.insert(wave2DeadAnim, {func = AnimSay, args = {cyborg, loc("Oh, my! This is even more entertaining than I've expected!"), SAY_SAY, 7500}})
- table.insert(wave2DeadAnim, {func = AnimSay, args = {cyborg, loc("You might want to find a way to instantly kill arriving cannibals!"), SAY_SAY, 8000}})
- table.insert(wave2DeadAnim, {func = AnimSay, args = {cyborg, loc("I believe there's more of them."), SAY_SAY, 4000}})
- table.insert(wave2DeadAnim, {func = AnimSay, args = {cyborg, loc("I marked the place of their arrival. You're welcome!"), SAY_SAY, 6000}})
- table.insert(wave2DeadAnim, {func = AnimCustomFunction, args = {natives[wiseNum], PutCircles, {}}})
- table.insert(wave2DeadAnim, {func = AnimFollowGear, swh = false, args = {vCircs[1]}})
- table.insert(wave2DeadAnim, {func = AnimCustomFunction, args = {deployedHog, DeployHog, {}}})
- if nativesNum > 1 then
--- table.insert(wave2DeadAnim, {func = AnimCustomFunction, args = {natives[wiseNum], RestoreCyborg, {}}})
--- table.insert(wave2DeadAnim, {func = AnimOutOfNowhere, swh = false, args = {cyborg, cyborgPos2[1], cyborgPos2[2]}})
--- table.insert(wave2DeadAnim, {func = AnimTurn, args = {cyborg, "Left"}})
- table.insert(wave2DeadAnim, {func = AnimCustomFunction, args = {cyborg, IsolateNatives, {}}})
- table.insert(wave2DeadAnim, {func = AnimCustomFunction, args = {cyborg, PutCGI, {}}})
- table.insert(wave2DeadAnim, {func = AnimSay, args = {cyborg, loc("I want to see how it handles this!"), SAY_SAY, 6000}})
- end
- table.insert(wave2DeadAnim, {func = AnimSwitchHog, args = {deployedHog}})
- table.insert(wave2DeadAnim, {func = AnimDisappear, swh = false, args = {cyborg, 0, 0}})
- table.insert(wave2DeadAnim, {func = AnimCustomFunction, swh = false, args = {cyborg, HideCyborg, {}}})
- end
- AddSkipFunction(wave2DeadAnim, SkipWave2DeadAnim, {})
-end
-
-function IsolateNatives()
- PlaceGirder(710, 299, 6)
- PlaceGirder(690, 299, 6)
- PlaceGirder(761, 209, 4)
- PlaceGirder(921, 209, 4)
- PlaceGirder(1081, 209, 4)
- PlaceGirder(761, 189, 4)
- PlaceGirder(921, 189, 4)
- PlaceGirder(1081, 189, 4)
- PlaceGirder(761, 169, 4)
- PlaceGirder(921, 169, 4)
- PlaceGirder(1081, 169, 4)
- PlaceGirder(761, 149, 4)
- PlaceGirder(921, 149, 4)
- PlaceGirder(1081, 149, 4)
- PlaceGirder(761, 129, 4)
- PlaceGirder(921, 129, 4)
- PlaceGirder(1081, 129, 4)
- PlaceGirder(1120, 261, 2)
- PlaceGirder(1140, 261, 2)
- PlaceGirder(1160, 261, 2)
- AddAmmo(deployedHog, amDEagle, 0)
- AddAmmo(deployedHog, amFirePunch, 0)
-end
-
-function PutCGI()
- AddVisualGear(710, 299, vgtExplosion, 0, true)
- AddVisualGear(690, 299, vgtExplosion, 0, true)
- AddVisualGear(761, 209, vgtExplosion, 0, true)
- AddVisualGear(921, 209, vgtExplosion, 0, true)
- AddVisualGear(1081, 209, vgtExplosion, 0, true)
- AddVisualGear(761, 189, vgtExplosion, 0, true)
- AddVisualGear(921, 189, vgtExplosion, 0, true)
- AddVisualGear(1081, 189, vgtExplosion, 0, true)
- AddVisualGear(761, 169, vgtExplosion, 0, true)
- AddVisualGear(921, 169, vgtExplosion, 0, true)
- AddVisualGear(1081, 169, vgtExplosion, 0, true)
- AddVisualGear(761, 149, vgtExplosion, 0, true)
- AddVisualGear(921, 149, vgtExplosion, 0, true)
- AddVisualGear(1081, 149, vgtExplosion, 0, true)
- AddVisualGear(761, 129, vgtExplosion, 0, true)
- AddVisualGear(921, 129, vgtExplosion, 0, true)
- AddVisualGear(1081, 129, vgtExplosion, 0, true)
- AddVisualGear(1120, 261, vgtExplosion, 0, true)
- AddVisualGear(1140, 261, vgtExplosion, 0, true)
- AddVisualGear(1160, 261, vgtExplosion, 0, true)
-end
-
-function TeleportNatives()
- nativePos[waterNum] = {1100, 288}
- for i = 1, 7 do
- if nativeDead[i] ~= true then
- AnimTeleportGear(natives[i], unpack(nativePos[i]))
- end
- end
-end
-
-function TurnNatives(hog)
- for i = 1, 7 do
- if nativeDead[i] == false then
- if GetX(natives[i]) < GetX(hog) then
- AnimTurn(natives[i], "Right")
- else
- AnimTurn(natives[i], "Left")
- end
- end
- end
-end
-
-function DeployHog()
- AnimSwitchHog(deployedHog)
- AnimTeleportGear(deployedHog, unpack(deployedPos))
- if deployedHog ~= natives[wiseNum] then
- AnimSay(deployedHog, loc("Why me?!"), SAY_THINK, 2000)
- end
-end
-
-function SetupAfterChoiceAnim()
- for i = 7, 1, -1 do
- if nativeDead[i] ~= true then
- if natives[i] ~= spyHog then
- speakerHog = natives[i]
- end
- end
- end
- if choice == choiceEliminate then
- table.insert(afterChoiceAnim, {func = AnimWait, args = {speakerHog, 1500}})
- table.insert(afterChoiceAnim, {func = AnimSay, args = {speakerHog, loc("He won't be selling us out anymore!"), SAY_SAY, 6000}})
- if nativeDead[girlNum] ~= true and m4ChiefDead == 1 then
- table.insert(afterChoiceAnim, {func = AnimSay, args = {natives[girlNum], loc("That's for my father!"), SAY_SAY, 3500}})
- end
- table.insert(afterChoiceAnim, {func = AnimSay, args = {speakerHog, loc("Let's show those cannibals what we're made of!"), SAY_SAY, 7000}})
- else
- table.insert(afterChoiceAnim, {func = AnimCustomFunction, swh = false, args = {natives[leaksNum], CondNeedToTurn, {speakerHog, spyHog}}})
- table.insert(afterChoiceAnim, {func = AnimSay, args = {speakerHog, loc("We'll spare your life for now!"), SAY_SAY, 4500}})
- table.insert(afterChoiceAnim, {func = AnimSay, args = {spyHog, loc("May the spirits aid you in all your quests!"), SAY_SAY, 7000}})
- table.insert(afterChoiceAnim, {func = AnimSay, args = {speakerHog, loc("I just don't want to sink to your level."), SAY_SAY, 6000}})
- table.insert(afterChoiceAnim, {func = AnimSay, args = {speakerHog, loc("Let's show those cannibals what we're made of!"), SAY_SAY, 7000}})
- end
- table.insert(afterChoiceAnim, {func = AnimSay, args = {natives[8], loc("Let us help, too!"), SAY_SAY, 3000}})
- table.insert(afterChoiceAnim, {func = AnimTurn, args = {speakerHog, "Left", SAY_SAY, 7000}})
- table.insert(afterChoiceAnim, {func = AnimSay, args = {speakerHog, loc("No. You and the rest of the tribe are safer there!"), SAY_SAY, 7000}})
- AddSkipFunction(afterChoiceAnim, SkipAfterChoiceAnim, {})
-end
-
-function SetupHogDeadAnim(gear)
- hogDeadAnim = {}
- if nativesNum == 0 then
- return
- end
- local hogDeadStrings = {loc("They killed ") .. gear .. loc("! You bastards!"),
- gear .. loc("! Why?!"),
- loc("That was just mean!"),
- loc("Oh no, not ") .. gear .. "!",
- loc("Why ") .. gear .. loc("? Why?"),
- loc("What has ") .. gear .. loc(" ever done to you?!")}
- table.insert(hogDeadAnim, {func = AnimSay, args = {CurrentHedgehog, hogDeadStrings[7 - nativesNum], SAY_SHOUT, 4000}})
-end
-
-function AfterHogDeadAnim()
- freshDead = nil
- TurnTimeLeft = TurnTime
-end
-
---------------------------Anim skip functions--------------------------
-
-function AfterAfterChoiceAnim()
- stage = 0
- AddEvent(CheckWaveDead, {1}, DoWaveDead, {1}, 0)
- AddAmmo(speakerHog, amSwitch, 100)
- SetGearMessage(speakerHog, 0)
- SetState(speakerHog, 0)
- TurnTimeLeft = -1
- ShowMission(loc("Backstab"), loc("The food bites back"), loc("Defeat the cannibals"), 1, 4000)
- SpawnCrates()
-end
-
-function SkipAfterChoiceAnim()
- SetGearMessage(CurrentHedgehog, 0)
- AnimSwitchHog(speakerHog)
-end
-
-function AfterWave2Anim()
- AddEvent(CheckWaveDead, {2}, DoWaveDead, {2}, 0)
- SetGearMessage(CurrentHedgehog, 0)
- SetState(CurrentHedgehog, 0)
- SpawnCrates()
- TurnTimeLeft = TurnTime
-end
-
-function SkipWave2DeadAnim()
- TeleportNatives()
- IsolateNatives()
- DeployHog()
- HideCyborg()
- PutCircles()
-end
-
-function SpawnPlatformCrates()
- SpawnAmmoCrate(2494, 1262, amMine)
- SpawnAmmoCrate(2574, 1279, amSMine)
- SpawnAmmoCrate(2575, 1267, amMine)
- SpawnAmmoCrate(2617, 1259, amSMine)
- SpawnUtilityCrate(2579, 1254, amMine)
- SpawnUtilityCrate(2478, 1243, amMine)
-end
-
-function AfterWave2DeadAnim()
- TurnsLeft = 7
- stage = platformStage
- SpawnPlatformCrates()
- SetGearMessage(CurrentHedgehog, 0)
- AddEvent(CheckTurnsOver, {}, DoTurnsOver, {3}, 0)
- AddEvent(CheckWaveDead, {3}, DoWaveDead, {3}, 0)
- AddEvent(CheckDeployedDead, {}, DoDeployedDead, {}, 0)
- TurnTimeLeft = 0
- ShowMission(loc("Backstab"), loc("Drills"), loc("You have 7 turns until the next wave arrives.|Make sure the arriving cannibals are greeted appropriately!|If the hog dies, the cause is lost.|Hint: you might want to use some mines..."), 1, 12000)
-end
-
-function DoTurnsOver()
- stage = wave3Stage
- RestoreWave(3)
-end
-
-function SkipWave2Anim()
- AnimSwitchHog(speakerHog)
-end
-
-function SkipStartAnim()
- AnimSetGearPosition(natives[waterNum], nativePos[denseNum][1] + 50, nativePos[denseNum][2])
- RestoreWave(1)
- ReviveNatives()
- SetGearMessage(CurrentHedgehog, 0)
- SetState(CurrentHedgehog, 0)
- if m2Choice == choiceAccepted then
- spyHog = natives[denseNum]
- else
- spyHog = natives[waterNum]
- end
- SetHealth(spyHog, 26)
-end
-
-function AfterStartAnim()
- AnimSwitchHog(natives[leaksNum])
- TurnTimeLeft = 0
- stage = spyKillStage
- AddEvent(CheckChoice, {}, DoChoice, {}, 0)
- AddEvent(CheckKilledOther, {}, DoKilledOther, {}, 0)
- AddEvent(CheckChoiceRefuse, {}, DoChoiceRefuse, {}, 0)
- ShowMission(loc("Backstab"), loc("Judas"), loc("Kill the traitor...or spare his life!|Kill him or press [Precise]!"), 1, 8000)
-end
-
------------------------------Events------------------------------------
-function CheckTurnsOver()
- return TurnsLeft == 0
-end
-
-function CheckDeployedDead()
- return deployedDead
-end
-
-function DoDeployedDead()
- ShowMission(loc("Backstab"), loc("Brutus"), loc("You have failed to save the tribe!"), 0, 6000)
- ParseCommand("teamgone " .. loc("Natives"))
- ParseCommand("teamgone " .. loc("Tribe"))
- ParseCommand("teamgone " .. loc("011101001"))
- TurnTimeLeft = 0
-end
-
-function CheckChoice()
- return choice ~= 0 and tmpVar == 0
-end
-
-function CheckDeaths()
- for i = 1, 7 do
- if natives[i] ~= spyHog and band(GetState(natives[i]), gstAttacked) ~= 0 then
- return true
- end
- end
- return false
-end
-
-function DoChoice()
- RemoveEventFunc(CheckChoiceRefuse)
- SetGearMessage(CurrentHedgehog, 0)
- SetupAfterChoiceAnim()
- AddAnim(afterChoiceAnim)
- AddFunction({func = AfterAfterChoiceAnim, args = {}})
-end
-
-function CheckChoiceRefuse()
- return highJumped == true and StoppedGear(CurrentHedgehog)
-end
-
-function DoChoiceRefuse()
- choice = choiceSpare
-end
-
-function CheckKilledOther()
- if stage ~= spyKillStage then
- return false
- end
- return (nativesNum < startNativesNum and choice ~= choiceEliminate) or
- (nativesNum < startNativesNum - 1 and choice == choiceEliminate)
-end
-
-function DoKilledOther()
- ShowMission(loc("Backstab"), loc("Brutus"), loc("You have killed an innocent hedgehog!"), 0, 6000)
- ParseCommand("teamgone " .. loc("Natives"))
- ParseCommand("teamgone " .. loc("Tribe"))
- TurnTimeLeft = 0
-end
-
-function CheckWaveDead(index)
- for i = (index - 1) * 3 + 1, index * 3 do
- if cannibalDead[i] ~= true or CurrentHedgehog == cannibals[i] then
- return false
- end
- end
- return true
-end
-
-function DoWaveDead(index)
- TurnTimeLeft = 0
- needToAct = index
-end
-
-function AddWave3DeadAnim()
- AnimSwitchHog(deployedHog)
- AnimWait(deployedHog, 1)
- AddFunction({func = HideNatives, args = {}})
- AddFunction({func = SetupWave3DeadAnim, args = {}})
- AddFunction({func = AddAnim, args = {wave3DeadAnim}})
- AddFunction({func = AddFunction, args = {{func = AfterWave3DeadAnim, args = {}}}})
-end
-
-function HideNatives()
- for i = 1, 9 do
- if nativeDead[i] ~= true and natives[i] ~= deployedHog then
- if nativeHidden[i] ~= true then
- HideHog(natives[i])
- nativeHidden[i] = true
- end
- end
- end
-end
-
-function SetupWave3DeadAnim()
- table.insert(wave3DeadAnim, {func = AnimTurn, args = {deployedHog, "Left"}})
- table.insert(wave3DeadAnim, {func = AnimSay, args = {deployedHog, loc("That ought to show them!"), SAY_SAY, 4000}})
- table.insert(wave3DeadAnim, {func = AnimSay, args = {deployedHog, loc("Guys, do you think there's more of them?"), SAY_SHOUT, 7000}})
- table.insert(wave3DeadAnim, {func = AnimVisualGear, args = {deployedHog, unpack(nativePos[wiseNum]), vgtFeather, 0, true, true}})
- table.insert(wave3DeadAnim, {func = AnimWait, args = {deployedHog, 1000}})
- table.insert(wave3DeadAnim, {func = AnimSay, args = {deployedHog, loc("Where are they?!"), SAY_THINK, 3000}})
- table.insert(wave3DeadAnim, {func = AnimCustomFunction, args = {deployedHog, RestoreCyborg, {}}})
- table.insert(wave3DeadAnim, {func = AnimOutOfNowhere, args = {cyborg, 4040, 782}})
- table.insert(wave3DeadAnim, {func = AnimSay, args = {cyborg, loc("These primitive people are so funny!"), SAY_THINK, 6500}})
- table.insert(wave3DeadAnim, {func = AnimMove, args = {cyborg, "Right", 4060, 0}})
- table.insert(wave3DeadAnim, {func = AnimSwitchHog, args = {deployedHog}})
- table.insert(wave3DeadAnim, {func = AnimWait, args = {deployedHog, 1}})
- table.insert(wave3DeadAnim, {func = AnimCustomFunction, args = {deployedHog, HideCyborg, {}}})
- table.insert(wave3DeadAnim, {func = AnimSay, args = {deployedHog, loc("I need to find the others!"), SAY_THINK, 4500}})
- table.insert(wave3DeadAnim, {func = AnimSay, args = {deployedHog, loc("I have to follow that alien."), SAY_THINK, 4500}})
-end
-
-function SkipWave3DeadAnim()
- AnimSwitchHog(deployedHog)
-end
-
-function AfterWave3DeadAnim()
- if nativeDead[leaksNum] == true then
- SaveCampaignVar("M5LeaksDead", "1")
- else
- SaveCampaignVar("M5LeaksDead", "0")
- end
- if nativeDead[denseNum] == true then
- SaveCampaignVar("M5DenseDead", "1")
- else
- SaveCampaignVar("M5DenseDead", "0")
- end
- if nativeDead[waterNum] == true then
- SaveCampaignVar("M5WaterDead", "1")
- else
- SaveCampaignVar("M5WaterDead", "0")
- end
- if nativeDead[buffaloNum] == true then
- SaveCampaignVar("M5BuffaloDead", "1")
- else
- SaveCampaignVar("M5BuffaloDead", "0")
- end
- if nativeDead[girlNum] == true then
- SaveCampaignVar("M5GirlDead", "1")
- else
- SaveCampaignVar("M5GirlDead", "0")
- end
- if nativeDead[wiseNum] == true then
- SaveCampaignVar("M5WiseDead", "1")
- else
- SaveCampaignVar("M5WiseDead", "0")
- end
- if nativeDead[chiefNum] == true then
- SaveCampaignVar("M5ChiefDead", "1")
- else
- SaveCampaignVar("M5ChiefDead", "0")
- end
- SaveCampaignVar("M5Choice", "" .. choice)
- if progress and progress<5 then
- SaveCampaignVar("Progress", "5")
- end
-
- for i = 1, 7 do
- if natives[i] == deployedHog then
- SaveCampaignVar("M5DeployedNum", "" .. i)
- end
- end
-
- ParseCommand("teamgone " .. loc("Tribe"))
- ParseCommand("teamgone " .. loc("Assault Team"))
- ParseCommand("teamgone " .. loc("Reinforcements"))
- ParseCommand("teamgone " .. loc("011101001"))
- TurnTimeLeft = 0
-end
-
------------------------------Misc--------------------------------------
-
-function SpawnCrates()
- SpawnAmmoCrate(0, 0, amDrill)
- SpawnAmmoCrate(0, 0, amGrenade)
- SpawnAmmoCrate(0, 0, amBazooka)
- SpawnAmmoCrate(0, 0, amDynamite)
- SpawnAmmoCrate(0, 0, amGrenade)
- SpawnAmmoCrate(0, 0, amMine)
- SpawnAmmoCrate(0, 0, amShotgun)
- SpawnAmmoCrate(0, 0, amFlamethrower)
- SpawnAmmoCrate(0, 0, amMolotov)
- SpawnAmmoCrate(0, 0, amSMine)
- SpawnAmmoCrate(0, 0, amMortar)
- SpawnUtilityCrate(0, 0, amRope)
- SpawnUtilityCrate(0, 0, amRope)
- SpawnUtilityCrate(0, 0, amParachute)
- SpawnUtilityCrate(0, 0, amParachute)
- SetHealth(SpawnHealthCrate(0, 0), 25)
- SetHealth(SpawnHealthCrate(0, 0), 25)
- SetHealth(SpawnHealthCrate(0, 0), 25)
- SetHealth(SpawnHealthCrate(0, 0), 25)
- SetHealth(SpawnHealthCrate(0, 0), 25)
- SetHealth(SpawnHealthCrate(0, 0), 25)
-end
-
-
-function RestoreWave(index)
- for i = (index - 1) * 3 + 1, index * 3 do
- if cannibalHidden[i] == true then
- RestoreHog(cannibals[i])
- AnimSetGearPosition(cannibals[i], unpack(cannibalPos[i]))
- FollowGear(cannibals[i])
- cannibalHidden[i] = false
- end
- end
-end
-
-function GetVariables()
- progress = tonumber(GetCampaignVar("Progress"))
- m2DenseDead = tonumber(GetCampaignVar("M2DenseDead"))
- m2Choice = tonumber(GetCampaignVar("M2Choice"))
- m4DenseDead = tonumber(GetCampaignVar("M4DenseDead"))
- m4LeaksDead = tonumber(GetCampaignVar("M4LeaksDead"))
- m4ChiefDead = tonumber(GetCampaignVar("M4ChiefDead"))
- m4WaterDead = tonumber(GetCampaignVar("M4WaterDead"))
- m4BuffaloDead = tonumber(GetCampaignVar("M4BuffaloDead"))
-end
-
-function HideCyborg()
- if cyborgHidden == false then
- HideHog(cyborg)
- cyborgHidden = true
- end
-end
-
-function RestoreCyborg()
- if cyborgHidden == true then
- RestoreHog(cyborg)
- cyborgHidden = false
- end
-end
-
-function SetupPlace()
- startNativesNum = nativesNum
- HideHog(cyborg)
- cyborgHidden = true
- for i = 1, 9 do
- HideHog(cannibals[i])
- cannibalHidden[i] = true
- end
- if m4LeaksDead == 1 then
- HideHog(natives[leaksNum])
- nativeHidden[leaksNum] = true
- needRevival = true
- end
- if m4DenseDead == 1 then
- if m2Choice ~= choiceAccepted then
- DeleteGear(natives[denseNum])
- startNativesNum = startNativesNum - 1
- nativeDead[denseNum] = true
- else
- HideHog(natives[denseNum])
- nativeHidden[denseNum] = true
- needRevival = true
- end
- end
- if m4WaterDead == 1 then
- HideHog(natives[waterNum])
- nativeHidden[waterNum] = true
- needRevival = true
- end
- if m4ChiefDead == 1 then
- DeleteGear(natives[chiefNum])
- startNativesNum = startNativesNum - 1
- nativeDead[chiefNum] = true
- AnimSetGearPosition(natives[girlNum], unpack(nativePos[buffaloNum]))
- nativePos[girlNum] = nativePos[buffaloNum]
- end
- if m4BuffaloDead == 1 then
- startNativesNum = startNativesNum - 1
- nativeDead[buffaloNum] = true
- DeleteGear(natives[buffaloNum])
- end
- PlaceGirder(3568, 1461, 1)
- PlaceGirder(440, 523, 5)
- PlaceGirder(350, 441, 1)
- PlaceGirder(405, 553, 5)
- PlaceGirder(316, 468, 1)
- PlaceGirder(1319, 168, 0)
-end
-
-function SetupAmmo()
- AddAmmo(natives[girlNum], amSwitch, 0)
-end
-
-function AddHogs()
- AddTeam(loc("Natives"), 29439, "Bone", "Island", "HillBilly", "cm_birdy")
- for i = 1, 7 do
- natives[i] = AddHog(nativeNames[i], 0, 100, nativeHats[i])
- end
- nativesNum = 7
-
- AddTeam(loc("Tribe"), 29438, "Bone", "Island", "HillBilly", "cm_birdy")
- for i = 8, 9 do
- natives[i] = AddHog(nativeNames[i], 0, 100, nativeHats[i])
- end
-
-
- AddTeam(loc("Assault Team"), 14483456, "Skull", "Island", "Pirate", "cm_vampire")
- for i = 1, 6 do
- cannibals[i] = AddHog(cannibalNames[i], 1, 50, "vampirichog")
- end
-
- AddTeam(loc("Reinforcements"), 14483456, "Skull", "Island", "Pirate", "cm_vampire")
- for i = 7, 9 do
- cannibals[i] = AddHog(cannibalNames[i], 1, 50, "vampirichog")
- end
-
- AddTeam(loc("011101001"), 14483456, "ring", "UFO", "Robot", "cm_star")
- cyborg = AddHog(loc("Unit 334a$7%;.*"), 0, 200, "cyborg1")
-
- for i = 1, 9 do
- AnimSetGearPosition(natives[i], unpack(nativePos[i]))
- AnimTurn(natives[i], nativeDir[i])
- end
-
- AnimSetGearPosition(cyborg, 0, 0)
-
- for i = 1, 9 do
- AnimSetGearPosition(cannibals[i], cannibalPos[i][1], cannibalPos[i][2] + 40)
- AnimTurn(cannibals[i], cannibalDir[i])
- end
-end
-
-function CondNeedToTurn(hog1, hog2)
- xl, xd = GetX(hog1), GetX(hog2)
- if xl > xd then
- AnimInsertStepNext({func = AnimTurn, args = {hog1, "Left"}})
- AnimInsertStepNext({func = AnimTurn, args = {hog2, "Right"}})
- elseif xl < xd then
- AnimInsertStepNext({func = AnimTurn, args = {hog2, "Left"}})
- AnimInsertStepNext({func = AnimTurn, args = {hog1, "Right"}})
- end
-end
-
------------------------------Main Functions----------------------------
-
-function onGameInit()
- Seed = 2
- GameFlags = gfSolidLand
- TurnTime = 60000
- CaseFreq = 0
- MinesNum = 0
- MinesTime = 3000
- Explosives = 0
- Delay = 10
- Map = "Cave"
- Theme = "Nature"
- SuddenDeathTurns = 3000
-
- AddHogs()
- AnimInit()
-end
-
-function onGameStart()
- GetVariables()
- SetupAmmo()
- SetupPlace()
- AnimationSetup()
- AddAnim(startAnim)
- AddFunction({func = AfterStartAnim, args = {}})
-end
-
-function onGameTick()
- AnimUnWait()
- if ShowAnimation() == false then
- return
- end
- ExecuteAfterAnimations()
- CheckEvents()
-end
-
-function onGearDelete(gear)
- for i = 1, 7 do
- if gear == natives[i] then
- if nativeDead[i] ~= true then
- freshDead = nativeNames[i]
- end
- nativeDead[i] = true
- nativesNum = nativesNum - 1
- end
- end
-
- for i = 1, 9 do
- if gear == cannibals[i] then
- cannibalDead[i] = true
- end
- end
-
- if gear == spyHog and stage == spyKillStage then
- freshDead = nil
- choice = choiceEliminate
- tmpVar = 1
- end
-
- if gear == deployedHog then
- deployedDead = true
- end
-end
-
-function onAmmoStoreInit()
- SetAmmo(amDEagle, 9, 0, 0, 0)
- SetAmmo(amSniperRifle, 4, 0, 0, 0)
- SetAmmo(amFirePunch, 9, 0, 0, 0)
- SetAmmo(amWhip, 9, 0, 0, 0)
- SetAmmo(amBaseballBat, 9, 0, 0, 0)
- SetAmmo(amHammer, 9, 0, 0, 0)
- SetAmmo(amLandGun, 9, 0, 0, 0)
- SetAmmo(amSnowball, 8, 0, 0, 0)
- SetAmmo(amGirder, 4, 0, 0, 2)
- SetAmmo(amParachute, 4, 0, 0, 2)
- SetAmmo(amSwitch, 8, 0, 0, 2)
- SetAmmo(amSkip, 8, 0, 0, 0)
- SetAmmo(amRope, 5, 0, 0, 3)
- SetAmmo(amBlowTorch, 3, 0, 0, 3)
- SetAmmo(amPickHammer, 0, 0, 0, 3)
- SetAmmo(amLowGravity, 0, 0, 0, 2)
- SetAmmo(amDynamite, 0, 0, 0, 3)
- SetAmmo(amBazooka, 4, 0, 0, 4)
- SetAmmo(amGrenade, 4, 0, 0, 4)
- SetAmmo(amMine, 2, 0, 0, 2)
- SetAmmo(amSMine, 2, 0, 0, 2)
- SetAmmo(amMolotov, 2, 0, 0, 3)
- SetAmmo(amFlamethrower, 2, 0, 0, 3)
- SetAmmo(amShotgun, 4, 0, 0, 4)
- SetAmmo(amTeleport, 0, 0, 0, 2)
- SetAmmo(amDrill, 0, 0, 0, 4)
- SetAmmo(amMortar, 0, 0, 0, 4)
-end
-
-j = 0
-
-function onNewTurn()
- tmpVar = 0
- if AnimInProgress() then
- TurnTimeLeft = -1
- return
- end
-
- if GetHogTeamName(CurrentHedgehog) == loc("Tribe") then
- TurnTimeLeft = 0
- return
- end
- TurnsLeft = TurnsLeft - 1
-
- if stage == platformStage then
- AddCaption(TurnsLeft .. " turns until arrival!")
- end
-
- if stage == spyKillStage then
- if CurrentHedgehog == spyHog or GetHogTeamName(CurrentHedgehog) ~= loc("Natives") then
- TurnTimeLeft = 0
- else
- SetGearMessage(CurrentHedgehog, 0)
- --AnimSwitchHog(natives[leaksNum])
- TurnTimeLeft = -1
- end
- else
- if freshDead ~= nil and GetHogTeamName(CurrentHedgehog) == loc("Natives") then
- SetupHogDeadAnim(freshDead)
- AddAnim(hogDeadAnim)
- AddFunction({func = AfterHogDeadAnim, args = {}})
- end
- end
- if needToAct > 0 then
- if needToAct == 1 then
- RestoreWave(2)
- SetupWave2Anim()
- AddAnim(wave2Anim)
- AddFunction({func = AfterWave2Anim, args = {}})
- elseif needToAct == 2 then
- SetupWave2DeadAnim()
- AddAnim(wave2DeadAnim)
- AddFunction({func = AfterWave2DeadAnim, args = {}})
- elseif needToAct == 3 then
- AnimSwitchHog(deployedHog)
- AddFunction({func = AddWave3DeadAnim, args = {}})
- end
- needToAct = 0
- end
-end
-
-function onPrecise()
- if GameTime > 2500 and AnimInProgress() then
- SetAnimSkip(true)
- return
- end
- if stage == spyKillStage then
- highJumped = true
- end
-end
--- a/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/campaign.ini Mon Jul 01 22:28:42 2013 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-MissionNum=10
-ResetRetry=1
-
-[Mission 1]
-Name=First Blood
-Script=first_blood.lua
-
-[Mission 2]
-Name=The Shadow Falls
-Script=shadow.lua
-
-[Mission 3]
-Name=The Journey Back
-Script=journey.lua
-
-[Mission 4]
-Name=United We Stand
-Script=united.lua
-
-[Mission 5]
-Name=Backstab
-Script=backstab.lua
-
-[Mission 6]
-Name=Dragon's Lair
-Script=dragon.lua
-
-[Mission 7]
-Name=Family Reunion
-Script=family.lua
-
-[Mission 8]
-Name=Long Live The Queen
-Script=queen.lua
-
-[Mission 9]
-Name=The Enemy Of My Enemy
-Script=enemy.lua
-
-[Mission 10]
-Name=Epilogue
-Script=epil.lua
--- a/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/dragon.lua Mon Jul 01 22:28:42 2013 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,652 +0,0 @@
-HedgewarsScriptLoad("/Scripts/Locale.lua")
-HedgewarsScriptLoad("/Scripts/Animate.lua")
-
------------------------------Map--------------------------------------
-local map =
-{
- "\0\91\4\253\131\0\88\0\46\0\0\91\0\49\131\15\196\0\53\0\15\196\0\53\131\15\196\4\250\0\255\242\7\179\131\1\128\7\214\0",
- "\1\113\7\207\131\3\182\7\157\0\3\175\7\143\131\6\58\7\200\0\6\76\7\193\131\6\188\7\129\0\6\188\7\129\131\6\248\6\216\0",
- "\6\248\6\216\131\7\52\8\14\0\10\206\8\0\131\11\203\6\65\0\11\203\6\65\131\12\18\7\66\0\12\18\7\69\131\16\0\7\69\0",
- "\0\109\1\1\131\2\111\0\49\0\2\111\0\49\131\3\133\1\18\0\3\140\1\18\131\4\162\0\165\0\4\162\0\165\131\5\135\1\29\0",
- "\5\145\1\22\131\8\84\0\232\0\8\84\0\232\131\9\26\0\70\0\9\26\0\70\131\10\5\1\4\0\10\48\0\243\131\10\2\1\8\0",
- "\10\58\0\243\131\10\118\1\15\0\10\118\1\15\131\10\234\1\173\0\11\10\1\177\131\12\11\1\22\0\12\39\1\40\131\12\243\2\9\0",
- "\12\243\2\9\131\13\106\0\165\0\13\131\0\176\131\15\186\1\78\0\1\244\0\81\136\0\120\0\84\0\1\99\0\123\137\0\130\0\215\0",
- "\0\158\0\130\143\0\158\0\130\0\2\216\0\88\138\4\165\0\102\0\4\91\0\127\142\3\129\0\197\0\3\69\0\134\142\3\69\0\134\0",
- "\4\215\0\120\143\8\88\0\134\0\8\187\0\84\139\8\187\0\84\0\8\239\0\70\135\8\239\0\70\0\8\60\0\187\138\5\99\0\222\0",
- "\5\61\0\197\138\5\61\0\197\0\9\99\0\81\137\10\23\0\218\0\9\187\0\77\137\11\31\1\117\0\10\30\0\88\137\15\161\0\109\0",
- "\15\126\0\225\144\13\177\0\116\0\15\150\0\144\139\15\157\1\26\0\10\202\0\169\152\12\246\0\169\0\10\72\0\144\145\11\122\1\36\0",
- "\11\17\1\121\141\11\17\1\121\0\12\229\1\194\138\12\229\1\194\0\12\208\1\85\150\12\208\1\85\0\12\148\1\15\147\12\148\1\15\0",
- "\13\145\0\208\147\13\145\0\208\0\6\238\7\45\135\7\10\7\238\0\6\220\7\150\135\6\206\7\242\0\6\174\7\175\135\6\135\8\7\0",
- "\6\118\7\214\135\6\62\7\238\0\6\30\7\245\140\3\217\7\210\0\3\161\7\221\138\255\252\7\231\0\15\242\7\165\148\11\115\7\175\0",
- "\11\196\6\164\138\11\10\8\4\0\11\210\7\31\141\11\210\7\31\0\14\216\2\72\166\14\216\2\72\0\14\213\4\4\166\14\213\4\4\0",
- "\13\216\1\159\148\13\216\1\159\0\13\159\2\143\148\13\159\2\143\0\13\230\3\69\145\13\230\3\69\0\13\163\4\11\145\13\166\4\11\0",
- "\13\237\4\208\145\13\237\4\208\0\14\195\5\61\145\14\195\5\61\0\13\78\1\254\136\13\78\1\254\0\12\239\2\93\136\12\239\2\93\0",
- "\12\250\2\227\136\12\250\2\227\0\13\71\3\59\136\13\71\3\59\0\13\1\3\168\136\13\1\3\168\0\12\243\4\32\136\12\246\4\32\0",
- "\13\40\4\130\136\13\43\4\134\0\13\92\4\243\136\13\92\4\243\0\13\142\5\135\136\13\142\5\135\0\14\33\5\106\136\14\33\5\106\0",
- "\14\111\5\208\136\14\121\5\216\0\15\13\5\237\136\15\13\5\237\0\15\73\5\128\136\15\73\5\128\0\15\84\4\243\136\15\84\4\243\0",
- "\14\199\6\33\133\14\199\6\33\0\14\97\6\44\133\14\83\6\44\0\14\9\5\240\133\14\9\5\240\0\13\226\5\163\133\13\226\5\163\0",
- "\13\170\5\233\133\13\170\5\233\0\13\71\5\205\133\13\71\5\205\0\13\61\5\117\133\13\61\5\117\0\13\22\5\40\133\13\22\5\40\0",
- "\12\253\4\211\133\12\253\4\211\0\12\197\4\169\133\12\197\4\169\0\12\204\4\106\133\12\204\4\106\0\12\162\4\46\133\12\162\4\42\0",
- "\12\194\3\200\133\12\194\3\196\0\12\201\3\84\133\12\201\3\84\0\12\253\3\62\133\12\253\3\62\0\12\169\2\241\133\12\169\2\241\0",
- "\12\187\2\167\133\12\187\2\167\0\12\158\2\93\133\12\158\2\93\0\12\162\2\9\133\12\162\2\9\0\12\123\1\205\132\12\123\1\205\0",
- "\12\84\1\251\132\12\84\1\251\0\12\91\2\55\132\12\95\2\55\0\12\63\2\139\132\12\63\2\139\0\12\120\2\164\132\12\120\2\164\0",
- "\12\81\2\206\132\12\81\2\206\0\12\106\3\17\132\12\109\3\20\0\12\137\3\73\132\12\137\3\73\0\12\84\3\122\132\12\84\3\122\0",
- "\12\137\3\150\132\12\137\3\150\0\12\95\3\217\132\12\95\3\217\0\12\134\3\231\132\12\134\3\231\0\12\106\4\63\132\12\106\4\63\0",
- "\12\137\4\120\132\12\141\4\120\0\12\88\4\179\132\12\88\4\183\0\12\134\4\190\132\12\134\4\190\0\12\158\4\232\132\12\165\4\232\0",
- "\12\215\5\15\132\12\215\5\15\0\12\91\4\243\130\12\91\4\243\0\12\144\5\26\130\12\144\5\26\0\12\176\5\54\130\12\176\5\54\0",
- "\12\225\5\82\130\12\225\5\82\0\13\4\5\117\130\13\1\5\117\0\12\239\5\166\130\12\239\5\166\0\13\8\5\184\130\13\11\5\184\0",
- "\13\8\5\226\130\13\8\5\226\0\13\54\6\12\130\13\57\6\12\0\13\106\6\2\130\13\106\5\254\0\13\138\6\12\130\13\138\6\12\0",
- "\13\184\6\30\130\13\187\6\30\0\13\223\5\254\130\13\223\5\254\0\13\149\6\69\130\13\145\6\69\0\13\128\6\33\130\13\128\6\33\0",
- "\13\85\6\40\130\13\85\6\40\0\12\232\6\2\130\12\232\6\2\0\12\204\5\205\130\12\204\5\201\0\12\183\5\159\130\12\183\5\156\0",
- "\12\211\5\128\130\12\211\5\128\0\12\165\5\103\130\12\165\5\103\0\12\123\5\64\130\12\120\5\64\0\12\81\5\71\130\12\81\5\71\0",
- "\12\84\5\18\130\12\84\5\18\0\12\39\4\243\130\12\39\4\243\0\12\35\4\194\130\12\35\4\194\0\12\63\4\127\130\12\63\4\127\0",
- "\12\91\4\106\130\12\91\4\106\0\12\53\4\60\130\12\53\4\60\0\12\74\4\25\130\12\84\4\21\0\12\120\4\4\130\12\120\4\4\0",
- "\12\42\3\231\130\12\42\3\231\0\12\39\3\189\130\12\42\3\186\0\12\60\3\175\130\12\60\3\175\0\12\39\3\133\130\12\39\3\133\0",
- "\12\70\3\73\130\12\70\3\73\0\12\25\3\77\130\12\25\3\77\0\12\42\3\13\130\12\46\3\13\0\12\81\3\31\130\12\81\3\31\0",
- "\12\32\2\213\130\12\32\2\213\0\12\14\2\178\130\12\14\2\178\0\12\42\2\181\130\12\46\2\181\0\12\14\2\128\130\12\14\2\128\0",
- "\12\39\2\100\130\12\42\2\100\0\12\74\2\104\130\12\77\2\104\0\12\106\2\135\130\12\109\2\135\0\12\39\2\72\130\12\39\2\69\0",
- "\12\35\2\37\130\12\35\2\37\0\12\32\2\2\130\12\32\2\2\0\12\28\1\226\130\12\28\1\223\0\12\63\1\208\130\12\63\1\208\0",
- "\12\84\1\173\130\12\84\1\170\0\12\63\1\159\130\12\60\1\159\0\12\39\1\113\130\12\39\1\113\0\12\14\1\96\130\12\11\1\96\0",
- "\11\228\1\131\130\11\228\1\135\0\12\7\1\149\130\12\7\1\149\0\12\21\1\177\130\12\25\1\177\0\11\242\1\201\130\11\242\1\201\0",
- "\13\226\6\58\130\13\226\6\58\0\14\16\6\40\130\14\16\6\40\0\13\208\6\86\130\13\208\6\86\0\13\247\6\111\130\13\247\6\114\0",
- "\13\184\6\121\130\13\184\6\121\0\13\198\6\146\130\13\201\6\146\0\13\244\6\139\130\13\244\6\139\0\13\223\6\185\130\13\223\6\185\0",
- "\13\173\6\199\130\13\173\6\199\0\13\159\6\171\130\13\159\6\171\0\13\138\6\220\130\13\138\6\220\0\13\184\6\238\130\13\184\6\238\0",
- "\13\208\6\223\130\13\208\6\223\0\13\216\7\10\130\13\216\7\10\0\13\184\7\10\130\13\180\7\10\0\13\142\7\38\130\13\142\7\41\0",
- "\13\128\7\6\130\13\128\7\6\0\13\85\7\34\130\13\89\7\34\0\13\89\7\3\130\13\89\7\3\0\13\117\6\220\130\13\121\6\220\0",
- "\13\75\6\195\130\13\75\6\195\0\13\110\6\164\130\13\110\6\164\0\13\156\6\125\130\13\156\6\125\0\13\106\6\135\130\13\106\6\135\0",
- "\13\103\6\100\130\13\103\6\100\0\13\64\6\143\130\13\64\6\143\0\13\47\6\104\130\13\47\6\104\0\13\71\6\79\130\13\71\6\79\0",
- "\13\40\6\65\130\13\36\6\65\0\13\8\6\44\130\13\1\6\44\0\13\8\6\76\130\13\8\6\76\0\13\1\6\132\130\13\1\6\132\0",
- "\13\33\6\135\130\13\33\6\135\0\13\26\6\178\130\13\22\6\178\0\13\47\6\202\130\13\50\6\202\0\13\54\6\245\130\13\54\6\245\0",
- "\13\22\7\3\130\13\22\7\3\0\13\43\7\27\130\13\43\7\27\0\12\253\6\248\130\12\250\6\248\0\12\253\6\220\130\12\253\6\220\0",
- "\12\215\6\174\130\12\225\6\174\0\12\253\6\174\130\12\253\6\174\0\12\215\6\121\130\12\215\6\121\0\12\229\6\76\130\12\229\6\76\0",
- "\12\201\6\51\130\12\201\6\51\0\12\190\6\19\130\12\190\6\19\0\12\151\5\223\130\12\151\5\223\0\12\148\5\194\130\12\151\5\194\0",
- "\12\155\5\159\130\12\155\5\156\0\12\144\5\121\130\12\144\5\121\0\12\95\5\110\130\12\95\5\110\0\12\102\5\156\130\12\102\5\159\0",
- "\12\99\5\216\130\12\106\5\219\0\12\148\6\40\130\12\148\6\40\0\12\127\6\19\130\12\127\6\19\0\12\176\6\104\130\12\176\6\104\0",
- "\12\141\6\72\130\12\141\6\72\0\12\162\6\139\130\12\162\6\143\0\12\172\6\181\130\12\172\6\181\0\12\204\6\216\130\12\208\6\216\0",
- "\12\201\7\3\130\12\201\7\3\0\12\236\7\24\130\12\236\7\24\0\12\120\6\146\130\12\120\6\146\0\12\123\6\104\130\12\123\6\104\0",
- "\12\123\6\185\130\12\123\6\185\0\12\162\6\227\130\12\162\6\227\0\12\134\6\241\130\12\134\6\241\0\12\155\7\10\130\12\155\7\10\0",
- "\12\190\7\41\130\12\190\7\41\0\11\228\1\96\129\11\228\1\96\0\11\200\1\121\129\11\200\1\121\0\11\193\1\156\129\11\196\1\156\0",
- "\11\221\1\170\129\11\221\1\170\0\11\217\1\208\129\11\217\1\208\0\11\245\1\230\129\11\245\1\230\0\11\245\2\16\129\11\245\2\16\0",
- "\12\14\2\62\129\12\18\2\62\0\11\242\2\93\129\11\242\2\93\0\11\235\2\178\129\11\235\2\178\0\11\231\2\238\129\11\235\2\238\0",
- "\12\4\2\252\129\12\4\2\252\0\11\252\3\34\129\11\252\3\34\0\11\235\3\87\129\11\238\3\87\0\12\11\3\119\129\12\11\3\119\0",
- "\12\4\3\168\129\12\4\3\168\0\11\245\3\200\129\11\245\3\200\0\11\252\3\238\129\11\252\3\242\0\12\11\4\7\129\12\11\4\7\0",
- "\11\245\4\60\129\11\238\4\60\0\11\224\4\74\129\11\221\4\74\0\11\210\4\137\129\11\210\4\137\0\11\228\4\151\129\11\231\4\151\0",
- "\11\242\4\130\129\11\242\4\130\0\12\4\4\113\129\12\7\4\113\0\12\28\4\102\129\12\28\4\102\0\12\11\4\141\129\12\11\4\141\0",
- "\11\249\4\162\129\11\249\4\162\0\11\221\4\116\129\11\221\4\116\0\11\214\4\106\129\11\217\4\102\0\12\4\4\211\129\12\4\4\211\0",
- "\11\249\5\8\129\11\252\5\8\0\12\39\5\11\129\12\42\5\11\0\12\56\5\50\129\12\60\5\47\0\12\46\5\96\129\12\49\5\96\0",
- "\12\70\5\113\129\12\70\5\113\0\12\56\5\166\129\12\63\5\166\0\12\70\5\145\129\12\74\5\145\0\12\70\5\194\129\12\77\5\194\0",
- "\12\70\5\237\129\12\74\5\237\0\12\106\5\240\129\12\109\5\240\0\12\99\6\33\129\12\99\6\33\0\12\88\6\72\129\12\88\6\72\0",
- "\12\91\6\107\129\12\95\6\107\0\12\77\6\146\129\12\81\6\146\0\12\88\6\181\129\12\91\6\181\0\12\91\6\220\129\12\99\6\220\0",
- "\12\113\7\10\129\12\116\7\10\0\8\116\4\18\179\8\116\4\18\0\9\205\3\73\156\9\205\3\73\0\10\83\2\146\144\10\83\2\146\0",
- "\10\153\2\44\136\10\153\2\44\0\10\181\1\240\132\10\181\1\240\0\10\199\1\205\131\10\199\1\205\0\10\209\1\184\129\10\209\1\184\0",
- "\8\42\2\167\150\8\42\2\167\0\8\53\1\240\141\8\53\1\237\0\8\67\1\135\134\8\67\1\135\0\11\224\5\8\129\11\224\5\8\0",
- "\11\200\5\8\129\11\200\5\8\0\11\182\5\8\129\11\182\5\8\0\11\154\5\4\129\11\154\5\4\0\11\129\5\8\129\11\129\5\8\0",
- "\11\119\3\84\129\11\119\3\84\0\11\140\3\87\129\11\140\3\87\0\11\165\3\87\129\11\165\3\87\0\11\182\3\87\129\11\182\3\87\0",
- "\11\203\3\87\129\11\203\3\87\0\9\33\6\223\132\9\33\8\11\0\9\33\6\188\129\9\33\6\188\0\0\123\1\26\136\0\211\2\223\0",
- "\0\211\2\223\136\0\120\3\84\0\0\130\3\101\136\0\211\4\53\0\0\204\4\53\136\0\120\4\151\0\0\130\3\193\136\0\127\4\63\0",
- "\0\130\3\31\136\0\130\1\201\0\0\91\4\253\130\0\91\6\76\0\7\94\3\136\138\7\94\3\136\0\7\24\3\77\135\7\24\3\77\0",
- "\6\238\3\24\132\6\241\3\24\0\6\223\2\238\131\6\223\2\238\0\6\220\2\209\129\6\220\2\209\0\7\87\4\14\133\7\87\4\14\0",
- "\7\38\4\0\131\7\38\4\0\0\7\6\3\242\130\7\6\3\242\0\6\241\3\228\129\6\241\3\228\0\6\227\3\217\128\6\227\3\217\0",
- "\0\109\4\197\135\0\162\5\99\0\0\144\5\121\135\0\123\6\9\0\0\127\5\92\135\0\127\5\92\0\0\127\5\54\135\0\127\5\54\0",
- "\0\134\6\23\132\0\236\6\97\0\0\236\6\97\132\1\106\6\135\0\1\117\6\135\132\1\177\6\143\0\2\234\7\80\130\3\69\7\80\0",
- "\3\69\7\80\130\3\84\7\101\0\3\84\7\101\130\3\87\7\129\0\3\87\7\129\130\3\84\7\150\0\0\183\5\103\130\1\92\5\159\0",
- "\1\11\5\138\130\0\253\5\180\0\0\253\5\180\130\0\158\5\166\0\0\239\4\60\131\1\166\4\95\0\2\104\3\133\131\3\84\3\129\0",
- "\4\162\2\181\131\4\162\3\147\0\3\115\2\26\131\4\74\2\30\0\2\23\1\54\131\2\230\1\54\0\0\204\2\5\131\1\194\2\5\0",
- "\4\74\2\33\131\5\226\1\223\0\0\225\5\121\197\1\135\5\163\0\0\204\5\173\197\1\1\5\173\0\0\179\5\152\131\1\57\5\163\0",
- "\1\57\5\159\131\1\106\5\219\0\0\165\5\226\130\0\253\5\230\0\0\253\5\230\130\1\8\5\159\0\1\254\6\86\131\1\254\6\86\0",
- "\1\254\6\33\131\1\254\6\33\0\1\254\5\230\131\1\254\5\230\0\1\254\5\170\131\1\254\5\170\0\1\254\5\113\131\1\254\5\113\0",
- "\1\251\6\5\129\1\251\6\5\0\1\254\5\201\129\1\254\5\201\0\1\254\5\138\129\1\254\5\138\0\1\254\6\58\129\1\254\6\58\0",
- "\1\254\5\78\129\1\254\5\78\0\2\2\5\40\131\2\2\5\40\0\2\2\4\246\131\2\2\4\246\0\1\237\4\204\131\1\237\4\204\0",
- "\2\40\4\190\131\2\40\4\190\0\6\160\7\52\223\7\27\7\126\0\1\219\4\172\204\1\219\4\172\0\2\37\4\183\197\2\37\4\183\0",
- "\3\98\3\122\131\3\126\3\84\0\3\126\3\84\131\3\126\3\52\0\3\126\3\41\131\3\80\3\24\0\3\80\3\24\131\3\112\2\248\0",
- "\3\112\2\248\131\3\98\2\188\0",
-}
-
-
------------------------------Constants---------------------------------
-choiceAccepted = 1
-choiceRefused = 2
-choiceAttacked = 3
-
-choiceEliminate = 1
-choiceSpare = 2
-
-leaksNum = 1
-denseNum = 2
-waterNum = 3
-buffaloNum = 4
-chiefNum = 5
-girlNum = 6
-wiseNum = 7
-
-nativeNames = {loc("Leaks A Lot"), loc("Dense Cloud"), loc("Fiery Water"),
- loc("Raging Buffalo"), loc("Righteous Beard"), loc("Fell From Grace"),
- loc("Wise Oak")}
-
-nativeUnNames = {loc("Zork"), loc("Steve"), loc("Jack"),
- loc("Lee"), loc("Elmo"), loc("Rachel"),
- loc("Muriel")}
-
-nativeHats = {"Rambo", "RobinHood", "pirate_jack", "zoo_Bunny", "IndianChief",
- "tiara", "AkuAku"}
-
-nativePos = {257, 1950}
-
-cyborgNames = {loc("Syntax Errol"), loc("Segmentation Paul"), loc("Unexpected Igor"), loc("Jeremiah")}
-cyborgPos = {745, 1847}
-cyborgsPos = {{2937, 831}, {2945, 1264}, {2335, 1701}, {448, 484}}
-cyborgsDir = {"Left", "Left", "Left", "Right"}
-
-cratePos = {
- {788, 1919, amGirder, 2}, {412, 1615, amGirder, 1},
- {209, 1474, amSniperRifle, 1}, {1178, 637, amDEagle, 1},
- {633, 268, amDEagle, 1}, {3016, 1545, amDEagle, 1},
- {249, 1377, amRope, 3}, {330, 1018, amGirder, 1},
- {888, 647, amRope, 3}, {2116, 337, amRope, 3},
- {1779, 948, amRope, 3}, {3090, 1066, amRope, 3},
- {947, 480, amBazooka, 3}, {1097, 480, amMortar, 3},
- {1139, 451, amSnowball, 3}, {1207, 468, amShotgun, 3},
- {1024, 393, amSniperRifle, 2}, {998, 391, amDynamite, 2},
- {1024, 343, amRope, 2}, {998, 341, amRope, 2}
- }
-reactions = {loc("Yeah, take that!"), loc("Bullseye"), loc("Die, die, die!")}
-
-secondPos = {{1010, 510}, {1067, 510}}
------------------------------Variables---------------------------------
-natives = {}
-native = nil
-
-cyborgs = {}
-cyborg = {}
-cyborgsLeft = 0
-
-gearDead = {}
-hedgeHidden = {}
-
-startAnim = {}
-killAnim = {}
-killedAnim = {}
-
-freshDead = nil
-crates = {}
-cratesNum = 0
-jetCrate = nil
------------------------------Animations--------------------------------
-function EmitDenseClouds(dir)
- local dif
- if dir == "Left" then
- dif = 10
- else
- dif = -10
- end
- AnimInsertStepNext({func = AnimVisualGear, args = {native, GetX(native) + dif, GetY(native) + dif, vgtSteam, 0, true}, swh = false})
- AnimInsertStepNext({func = AnimVisualGear, args = {native, GetX(native) + dif, GetY(native) + dif, vgtSteam, 0, true}, swh = false})
- AnimInsertStepNext({func = AnimVisualGear, args = {native, GetX(native) + dif, GetY(native) + dif, vgtSteam, 0, true}, swh = false})
- AnimInsertStepNext({func = AnimWait, args = {native, 800}})
- AnimInsertStepNext({func = AnimVisualGear, args = {native, GetX(native) + dif, GetY(native) + dif, vgtSteam, 0, true}, swh = false})
- AnimInsertStepNext({func = AnimVisualGear, args = {native, GetX(native) + dif, GetY(native) + dif, vgtSteam, 0, true}, swh = false})
- AnimInsertStepNext({func = AnimWait, args = {native, 800}})
- AnimInsertStepNext({func = AnimVisualGear, args = {native, GetX(native) + dif, GetY(native) + dif, vgtSteam, 0, true}, swh = false})
-end
-
-function AnimationSetup()
- startAnim = {}
- local m = m5DeployedNum
- table.insert(startAnim, {func = AnimWait, args = {native, 3000}})
- table.insert(startAnim, {func = AnimCaption, args = {native, loc("With the rest of the tribe gone, it was up to ") .. nativeNames[m5DeployedNum] .. loc(" to save the village."), 5000}})
- table.insert(startAnim, {func = AnimCaption, args = {native, loc("But it proved to be no easy task!"), 2000}})
- for i = 1, 4 do
- table.insert(startAnim, {func = FollowGear, swh = false, args = {cyborgs[i]}})
- table.insert(startAnim, {func = AnimWait, args = {native, 1000}})
- end
- table.insert(startAnim, {func = FollowGear, swh = false, args = {native}})
- if m == leaksNum then
- table.insert(startAnim, {func = AnimMove, args = {native, "Right", nativePos[1] + 50, 0}})
- table.insert(startAnim, {func = AnimSay, args = {native, loc("What a strange cave!"), SAY_THINK, 0}})
- table.insert(startAnim, {func = AnimMove, args = {native, "Right", nativePos[1] + 200, 0}})
- table.insert(startAnim, {func = AnimSay, args = {native, loc("Now how do I get on the other side?!"), SAY_THINK, 5500}})
- elseif m == denseNum then
- table.insert(startAnim, {func = AnimMove, args = {native, "Right", nativePos[1] + 50, 0}})
- table.insert(startAnim, {func = AnimSay, args = {native, loc("Dude, what's this place?!"), SAY_THINK, 0}})
- table.insert(startAnim, {func = AnimCustomFunction, args = {native, EmitDenseClouds, {"Right"}}})
- table.insert(startAnim, {func = AnimMove, args = {native, "Right", nativePos[1] + 200, 0}})
- table.insert(startAnim, {func = AnimSay, args = {native, loc("And where's all the weed?"), SAY_THINK, 4000}})
- elseif m == waterNum then
- table.insert(startAnim, {func = AnimMove, args = {native, "Right", nativePos[1] + 50, 0}})
- table.insert(startAnim, {func = AnimSay, args = {native, loc("Is this place in my head?"), SAY_THINK, 0}})
- table.insert(startAnim, {func = AnimMove, args = {native, "Right", nativePos[1] + 200, 0}})
- table.insert(startAnim, {func = AnimSay, args = {native, loc("I shouldn't have drunk that last pint."), SAY_THINK, 6000}})
- elseif m == buffaloNum then
- table.insert(startAnim, {func = AnimMove, args = {native, "Right", nativePos[1] + 50, 0}})
- table.insert(startAnim, {func = AnimSay, args = {native, loc("Where did that alien run?"), SAY_THINK, 0}})
- table.insert(startAnim, {func = AnimMove, args = {native, "Right", nativePos[1] + 200, 0}})
- table.insert(startAnim, {func = AnimSay, args = {native, loc("When I find it..."), SAY_THINK, 3000}})
- elseif m == girlNum then
- table.insert(startAnim, {func = AnimMove, args = {native, "Right", nativePos[1] + 50, 0}})
- table.insert(startAnim, {func = AnimSay, args = {native, loc("This is typical!"), SAY_THINK, 0}})
- table.insert(startAnim, {func = AnimMove, args = {native, "Right", nativePos[1] + 200, 0}})
- table.insert(startAnim, {func = AnimSay, args = {native, loc("It's always up to women to clear up the mess men created!"), SAY_THINK, 8500}})
- elseif m == chiefNum then
- table.insert(startAnim, {func = AnimMove, args = {native, "Right", nativePos[1] + 50, 0}})
- table.insert(startAnim, {func = AnimSay, args = {native, loc("What is this place?"), SAY_THINK, 0}})
- table.insert(startAnim, {func = AnimMove, args = {native, "Right", nativePos[1] + 200, 0}})
- table.insert(startAnim, {func = AnimSay, args = {native, loc("It doesn't matter. I won't let that alien hurt my daughter!"), SAY_THINK, 8500}})
- elseif m == wiseNum then
- table.insert(startAnim, {func = AnimMove, args = {native, "Right", nativePos[1] + 50, 0}})
- table.insert(startAnim, {func = AnimSay, args = {native, loc("Every single time!"), SAY_THINK, 0}})
- table.insert(startAnim, {func = AnimMove, args = {native, "Right", nativePos[1] + 200, 0}})
- table.insert(startAnim, {func = AnimSay, args = {native, loc("How come in a village full of warriors, it's up to me to save it?"), SAY_THINK, 8500}})
- end
-
- table.insert(startAnim, {func = AnimCustomFunction, args = {native, RestoreHedge, {cyborg, unpack(cyborgPos)}}})
- table.insert(startAnim, {func = AnimOutOfNowhere, args = {cyborg, unpack(cyborgPos)}})
- table.insert(startAnim, {func = AnimTurn, args = {cyborg, "Left"}})
- table.insert(startAnim, {func = AnimSay, args = {cyborg, loc("Greetings, ") .. nativeUnNames[m] .. "!", SAY_SAY, 2500}})
- table.insert(startAnim, {func = AnimSay, args = {cyborg, loc("As you can see, there is no way to get on the other side!"), SAY_SAY, 7000}})
- table.insert(startAnim, {func = AnimSay, args = {cyborg, loc("I wish to help you, ") .. nativeUnNames[m] .. "!", SAY_SAY, 4000}})
- table.insert(startAnim, {func = AnimSay, args = {cyborg, loc("Beware, though! If you are slow, you die!"), SAY_SAY, 7000}})
- table.insert(startAnim, {func = AnimDisappear, args = {cyborg, unpack(cyborgPos)}})
- table.insert(startAnim, {func = AnimSwitchHog, args = {native}})
- table.insert(startAnim, {func = AnimCustomFunction, args = {native, HideHedge, {cyborg}}})
- table.insert(startAnim, {func = AnimSay, args = {native, loc("Talk about mixed signals..."), SAY_SAY, 4000}})
- AddSkipFunction(startAnim, SkipStartAnim, {})
-end
-
-function SetupKillAnim()
- table.insert(killAnim, {func = AnimSay, args = {native, loc("Well, that was a waste of time."), SAY_THINK, 5000}})
- table.insert(killAnim, {func = AnimCustomFunction, args = {native, RestoreHedge, {cyborg, unpack(cyborgPos)}}})
- table.insert(killAnim, {func = AnimOutOfNowhere, args = {cyborg, unpack(cyborgPos)}})
- table.insert(killAnim, {func = AnimCustomFunction, args = {cyborg, CondNeedToTurn, {cyborg, native}}})
- table.insert(killAnim, {func = AnimSay, args = {cyborg, loc("You bear impressive skills, ") .. nativeUnNames[m5DeployedNum] .. "!", SAY_SHOUT, 4000}})
- table.insert(killAnim, {func = AnimSay, args = {cyborg, loc("However, my mates don't agree with me on letting you go..."), SAY_SHOUT, 7000}})
- table.insert(killAnim, {func = AnimSay, args = {cyborg, loc("I guess you'll have to kill them."), SAY_SHOUT, 4000}})
- table.insert(killAnim, {func = AnimDisappear, args = {cyborg, unpack(cyborgPos)}})
- table.insert(killAnim, {func = AnimSwitchHog, args = {native}})
- table.insert(killAnim, {func = AnimWait, args = {native, 1}})
- table.insert(killAnim, {func = AnimCustomFunction, args = {native, HideHedge, {cyborg}}})
- AddSkipFunction(killAnim, SkipKillAnim, {})
-end
-
-function SetupKilledAnim()
- table.insert(killedAnim, {func = AnimWait, args = {cyborg, 500}})
- table.insert(killedAnim, {func = AnimOutOfNowhere, args = {cyborg, unpack(secondPos[2])}})
- table.insert(killedAnim, {func = AnimOutOfNowhere, args = {native, unpack(secondPos[1])}})
- table.insert(killedAnim, {func = AnimCustomFunction, args = {cyborg, CondNeedToTurn, {cyborg, native}}})
- table.insert(killedAnim, {func = AnimSay, args = {cyborg, loc("Nice work, ") .. nativeUnNames[m5DeployedNum] .. "!", SAY_SHOUT, 4000}})
- table.insert(killedAnim, {func = AnimSay, args = {cyborg, loc("As a reward for your performance, here's some new technology!"), SAY_SHOUT, 8000}})
- table.insert(killedAnim, {func = AnimSay, args = {cyborg, loc("Use it wisely!"), SAY_SHOUT, 3000}})
- table.insert(killedAnim, {func = AnimDisappear, args = {cyborg, unpack(secondPos[2])}})
- table.insert(killedAnim, {func = AnimSwitchHog, args = {native}})
- AddSkipFunction(killedAnim, SkipKilledAnim, {})
-end
---------------------------Anim skip functions--------------------------
-function SkipStartAnim()
- AnimSwitchHog(native)
- AnimWait(native, 1)
- AddFunction({func = HideHedge, args = {cyborg}})
-end
-
-function AfterStartAnim()
- SetGearMessage(native, 0)
- cratesNum = 0
- for i = 1, 6 do
- crates[i] = SpawnAmmoCrate(unpack(cratePos[i]))
- cratesNum = cratesNum + 1
- end
- FollowGear(native)
- AddNewEvent(CheckGearsDead, {{crates[1], crates[2]}}, PutCrates, {2}, 0)
- TurnTimeLeft = TurnTime
- ShowMission(loc("Dragon's Lair"), loc("Obstacle course"), loc("In order to get to the other side, you need to collect the crates first.|") ..
- loc("As the ammo is sparse, you might want to reuse ropes while mid-air.|") ..
- loc("If you wish to restart the course, hold [Precise] while your turn ends (e.g with Skip)!|") ..
- loc("The enemy can't move but it might be a good idea to stay out of sight!|") ..
- loc("You have ") .. SuddenDeathTurns .. loc(" turns until Sudden Death! Better hurry!"), 1, 0)
-end
-
-function SkipKillAnim()
- AnimSwitchHog(native)
- AnimWait(native, 1)
- AddFunction({func = HideHedge, args = {cyborg}})
-end
-
-function AfterKillAnim()
- PutWeaponCrates()
- TurnTimeLeft = TurnTime
- AddEvent(CheckCyborgsDead, {}, DoCyborgsDead, {}, 0)
- ShowMission(loc("Dragon's Lair"), loc("The Slaughter"), loc("Kill the aliens!"), 1, 2000)
-end
-
-function SkipKilledAnim()
- AnimSetGearPosition(native, unpack(secondPos[1]))
- AnimSwitchHog(native)
- AnimWait(native, 1)
-end
-
-function AfterKilledAnim()
- HideHedge(cyborg)
- TurnTimeLeft = TurnTime
- SetGearMessage(native, 0)
- AddAmmo(native, amPortalGun, 100)
- SpawnUtilityCrate(2259, 755, amTeleport, 2)
- SpawnHealthCrate(secondPos[1][1] + 30, secondPos[1][2])
- ShowMission(loc("Dragon's Lair"), loc("The what?!"), loc("Use the portal gun to get to the next crate, then use the new gun to get to the final destination!|")..
- loc("Portal hint: one goes to the destination, and one is the entrance.|")..
- loc("Teleport hint: just use the mouse to select the destination!"), 1, 0)
-end
------------------------------Events------------------------------------
-
-function CheckCyborgsDead()
- return cyborgsLeft == 0
-end
-
-function NullifyAmmo()
- AddAmmo(native, amRope, 0)
- AddAmmo(native, amGirder, 0)
- AddAmmo(native, amLowGravity, 0)
- AddAmmo(native, amBazooka, 0)
- AddAmmo(native, amSniperRifle, 0)
- AddAmmo(native, amDEagle, 0)
- AddAmmo(native, amDynamite, 0)
- AddAmmo(native, amFirePunch, 0)
- AddAmmo(native, amBaseballBat, 0)
- AddAmmo(native, amMortar, 0)
- AddAmmo(native, amSnowball, 0)
- AddAmmo(native, amShotgun, 0)
-end
-
-function DoCyborgsDead()
- NullifyAmmo()
- RestoreHedge(cyborg)
- SetupKilledAnim()
- SetGearMessage(CurrentHedgehog, 0)
- AddAnim(killedAnim)
- AddFunction({func = AfterKilledAnim, args = {}})
-end
-
-
-function PutWeaponCrates()
- for i = 1, 8 do
- cratesNum = cratesNum + 1
- crates[cratesNum] = SpawnAmmoCrate(unpack(cratePos[cratesNum]))
- end
- FollowGear(native)
-end
-
-function DoCratesTaken()
- SetupKillAnim()
- SetGearMessage(CurrentHedgehog, 0)
- AddAnim(killAnim)
- AddFunction({func = AfterKillAnim, args = {}})
-end
-
-function PutCrates(index)
- if index <= 7 then
- cratesNum = cratesNum + 1
- crates[cratesNum] = SpawnUtilityCrate(unpack(cratePos[cratesNum]))
- AddNewEvent(CheckGearDead, {crates[cratesNum]}, PutCrates, {index + 1}, 0)
- FollowGear(native)
- else
- AddEvent(StoppedGear, {native}, DoCratesTaken, {}, 0)
- end
- if index == 4 then
- AnimSay(native, loc("I'm a ninja."), SAY_THINK, 0)
- end
-end
-
-function CheckMissionFinished()
- return gearDead[jetCrate] == true
-end
-
-function DoMissionFinished()
- AddCaption(loc("Salvation was one step closer now..."))
- if progress and progress<6 then
- SaveCampaignVar("Progress", "6")
- end
- RestoreHedge(cyborg)
- DeleteGear(cyborg)
- TurnTimeLeft = 0
-end
-
-function CheckGearsDead(gearList)
- for i = 1, # gearList do
- if gearDead[gearList[i]] ~= true then
- return false
- end
- end
- return true
-end
-
-
-function CheckGearDead(gear)
- return gearDead[gear]
-end
-
-function EndMission()
- RestoreHedge(cyborg)
- DeleteGear(cyborg)
- TurnTimeLeft = 0
-end
-
-function CheckFreshDead()
- return freshDead ~= nil
-end
-
-function CyborgDeadReact()
- freshDead = nil
- if cyborgsLeft == 0 then
- return
- end
- AnimSay(native, reactions[cyborgsLeft])
-end
------------------------------Misc--------------------------------------
-function HideHedge(hedge)
- if hedgeHidden[hedge] ~= true then
- HideHog(hedge)
- hedgeHidden[hedge] = true
- end
-end
-
-function RestoreHedge(hedge)
- if hedgeHidden[hedge] == true then
- RestoreHog(hedge)
- hedgeHidden[hedge] = false
- end
-end
-
-function GetVariables()
- progress = tonumber(GetCampaignVar("Progress"))
- m5DeployedNum = tonumber(GetCampaignVar("M5DeployedNum"))
-end
-
-function SetupPlace()
- for i = 1, 7 do
- if i ~= m5DeployedNum then
- DeleteGear(natives[i])
- else
- native = natives[i]
- end
- end
- HideHedge(cyborg)
- jetCrate = SpawnUtilityCrate(3915, 1723, amJetpack)
-
- SetTimer(AddGear(1071, 1913, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(1098, 1919, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(1136, 1923, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(1170, 1930, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(1203, 1924, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(1228, 1939, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(1264, 1931, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(1309, 1938, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(1352, 1936, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(1386, 1939, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(1432, 1942, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(1483, 1950, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(1530, 1954, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(1579, 1959, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(1000, 1903, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(957, 1903, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(909, 1910, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(889, 1917, gtMine, 0, 0, 0, 0), 5000)
- ------ STICKY MINE LIST ------
- tempG = AddGear(1199, 733, gtSMine, 0, 0, 0, 0)
- tempG = AddGear(1195, 793, gtSMine, 0, 0, 0, 0)
- tempG = AddGear(1201, 861, gtSMine, 0, 0, 0, 0)
- tempG = AddGear(682, 878, gtSMine, 0, 0, 0, 0)
- tempG = AddGear(789, 876, gtSMine, 0, 0, 0, 0)
-end
-
-function SetupEvents()
- AddNewEvent(CheckMissionFinished, {}, DoMissionFinished, {}, 0)
- AddNewEvent(CheckGearDead, {native}, EndMission, {}, 0)
- AddNewEvent(CheckFreshDead, {}, CyborgDeadReact, {}, 1)
-end
-
-function SetupAmmo()
- AddAmmo(cyborgs[1], amBazooka, 100)
--- AddAmmo(cyborgs[1], amSniperRifle, 100)
- AddAmmo(cyborgs[1], amShotgun, 100)
- AddAmmo(cyborgs[1], amSwitch, 100)
-end
-
-function AddHogs()
- AddTeam(loc("Natives"), 29439, "Bone", "Island", "HillBilly", "cm_birdy")
- for i = 1, 7 do
- natives[i] = AddHog(nativeNames[i], 0, 200, nativeHats[i])
- gearDead[natives[i]] = false
- end
-
- AddTeam(loc("011101001"), 14483456, "ring", "UFO", "Robot", "cm_star")
- cyborg = AddHog(loc("Unit 334a$7%;.*"), 0, 200, "cyborg1")
- gearDead[cyborg] = false
-
- AddTeam(loc("011101000"), 14483455, "ring", "UFO", "Robot", "cm_star")
- for i = 1, 4 do
- cyborgs[i] = AddHog(cyborgNames[i], 2, 100, "cyborg2")
- gearDead[cyborgs[i]] = false
- end
- cyborgsLeft = 4
-
- for i = 1, 7 do
- AnimSetGearPosition(natives[i], unpack(nativePos))
- end
-
- AnimSetGearPosition(cyborg, unpack(cyborgPos))
-
- for i = 1, 4 do
- AnimSetGearPosition(cyborgs[i], unpack(cyborgsPos[i]))
- AnimTurn(cyborgs[i], cyborgsDir[i])
- end
-
-end
-
-function CondNeedToTurn(hog1, hog2)
- xl, xd = GetX(hog1), GetX(hog2)
- if xl > xd then
- AnimInsertStepNext({func = AnimTurn, args = {hog1, "Left"}})
- AnimInsertStepNext({func = AnimTurn, args = {hog2, "Right"}})
- elseif xl < xd then
- AnimInsertStepNext({func = AnimTurn, args = {hog2, "Left"}})
- AnimInsertStepNext({func = AnimTurn, args = {hog1, "Right"}})
- end
-end
-
------------------------------Main Functions----------------------------
-
-function onGameInit()
- Seed = 0
- GameFlags = gfSolidLand + gfDisableLandObjects + gfDisableWind + gfDisableGirders
- TurnTime = 60000
- CaseFreq = 0
- MinesNum = 20
- MinesTime = 3000
- Explosives = 6
- Delay = 10
- MapGen = 2
- Theme = "City"
- SuddenDeathTurns = 25
-
- for i = 1, #map do
- ParseCommand('draw ' .. map[i])
- end
-
- AddHogs()
- AnimInit()
-end
-
-function onGameStart()
- GetVariables()
- SetupAmmo()
- SetupPlace()
- AnimationSetup()
- SetupEvents()
- AddAnim(startAnim)
- AddFunction({func = AfterStartAnim, args = {}})
- ShowMission(loc("Dragon's Lair"), loc("Y Chwiliad"), loc("Find your tribe!|Cross the lake!"), 1, 0)
-end
-
-function onGameTick()
- AnimUnWait()
- if ShowAnimation() == false then
- return
- end
- ExecuteAfterAnimations()
- CheckEvents()
-end
-
-function onGearDelete(gear)
- gearDead[gear] = true
- if GetGearType(gear) == gtHedgehog then
- if GetHogTeamName(gear) == loc("011101000") then
- freshDead = GetHogName(gear)
- cyborgsLeft = cyborgsLeft - 1
- end
- end
-end
-
-function onAmmoStoreInit()
- SetAmmo(amFirePunch, 3, 0, 0, 0)
- SetAmmo(amBaseballBat, 2, 0, 0, 0)
- SetAmmo(amGirder, 0, 0, 0, 2)
- SetAmmo(amLowGravity, 0, 0, 0, 1)
- SetAmmo(amSkip, 9, 0, 0, 0)
-end
-
-function onNewTurn()
- if AnimInProgress() then
- TurnTimeLeft = -1
- return
- end
- if GetHogTeamName(CurrentHedgehog) == loc("011101000") then
- SetInputMask(band(0xFFFFFFFF, bnot(gmLeft + gmRight + gmLJump + gmHJump)))
- for i = 1, 4 do
- if gearDead[CurrentHedgehog] ~= true and gearDead[native] ~= true then
- if gearDead[cyborgs[i]] ~= true and GetX(cyborgs[i]) < GetX(native) then
- HogTurnLeft(cyborgs[i], false)
- else
- HogTurnLeft(cyborgs[i], true)
- end
- end
- end
- if TotalRounds % 6 == 0 then
- AddAmmo(CurrentHedgehog, amSniperRifle, 1)
- AddAmmo(CurrentHedgehog, amDEagle, 1)
- end
- TurnTimeLeft = 30000
- elseif GetHogTeamName(CurrentHedgehog) == loc("011101001") then
- TurnTimeLeft = 0
- else
- SetInputMask(0xFFFFFFFF)
- AddCaption(loc("Turns until Sudden Death: ") .. SuddenDeathTurns - TotalRounds)
- end
-end
-
-function onPrecise()
- if GameTime > 2500 and AnimInProgress() then
- SetAnimSkip(true)
- end
- if AnimInProgress() == false then
- end
-end
-
-function onPreciseUp()
-end
--- a/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/enemy.lua Mon Jul 01 22:28:42 2013 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,666 +0,0 @@
-HedgewarsScriptLoad("/Scripts/Locale.lua")
-HedgewarsScriptLoad("/Scripts/Animate.lua")
-
-
---------------------------------------------Constants------------------------------------
-choiceAccepted = 1
-choiceRefused = 2
-choiceAttacked = 3
-
-choiceEliminate = 1
-choiceSpare = 2
-
-leaksNum = 1
-denseNum = 2
-waterNum = 3
-buffaloNum = 4
-chiefNum = 5
-girlNum = 6
-wiseNum = 7
-ramonNum = 8
-spikyNum = 9
-
-denseScene = 1
-princessScene = 2
-waterScene = 3
-cyborgScene = 4
-
-nativeNames = {loc("Leaks A Lot"), loc("Dense Cloud"), loc("Fiery Water"),
- loc("Raging Buffalo"), loc("Righteous Beard"), loc("Fell From Grace"),
- loc("Wise Oak"), loc("Ramon"), loc("Spiky Cheese")
- }
-
-nativeHats = {"Rambo", "RobinHood", "pirate_jack", "zoo_Bunny", "IndianChief",
- "tiara", "AkuAku", "rasta", "hair_yellow"}
-
-nativePos = {{1259, 120}, {2378, 796}, {424, 1299}, {3322, 260}, {1022, 1550}}
-nativeDir = {"Right", "Left", "Right", "Left", "Right"}
-
-cannibalNames = {loc("Honest Lee"), loc("Vegan Jack"), loc("Sirius Lee"),
- loc("Brutal Lily")}
-cannibalPos = {{162, 266}, {2159, 1517}, {3311, 1621}, {1180, 1560}}
-cannibalDir = {"Right", "Left", "Left", "Right"}
-cannibalsNum = 4
-
-playersDir = {"Right", "Left", "Right", "Left", "Right", "Right", "Left", "Left", "Right"}
-playersAntiDir = {"Left", "Right", "Left", "Right", "Left", "Left", "Right", "Right", "Left"}
-
-cyborgNames = {loc("Smith 0.97"), loc("Smith 0.98"), loc("Smith 0.99a"),
- loc("Smith 0.99b"), loc("Smith 0.99f"), loc("Smith 1.0")}
-cyborgPos = {{2162, 20}, {2458, 564}, {542, 1133}, {3334, 1427}}
-cyborgDir = "Right"
-cyborgsNum = 6
-cyborgsPos = {{1490, 330}, {1737, 1005}, {2972, 922}, {1341, 1571},
- {751, 543}, {3889, 907}}
-cyborgsDir = {"Right", "Right", "Left", "Right", "Right", "Left"}
-
-leaderPos = {3474, 151}
-leaderDir = "Left"
-
------------------------------Variables---------------------------------
-natives = {}
-origNatives = {}
-
-cyborgs = {}
-cyborg = nil
-
-cannibals = {}
-players = {}
-leader = nil
-
-gearDead = {}
-hedgeHidden = {}
-
-startAnim = {}
-finalAnim = {}
------------------------------Animations--------------------------------
-function CondNeedToTurn(hog1, hog2)
- xl, xd = GetX(hog1), GetX(hog2)
- if xl > xd then
- AnimInsertStepNext({func = AnimTurn, args = {hog1, "Left"}})
- AnimInsertStepNext({func = AnimTurn, args = {hog2, "Right"}})
- elseif xl < xd then
- AnimInsertStepNext({func = AnimTurn, args = {hog2, "Left"}})
- AnimInsertStepNext({func = AnimTurn, args = {hog1, "Right"}})
- end
-end
-
-function CondNeedToTurn2(hog1, hog2)
- xl, xd = GetX(hog1), GetX(hog2)
- if xl > xd then
- AnimTurn(hog1, "Left")
- AnimTurn(hog2, "Right")
- elseif xl < xd then
- AnimTurn(hog2, "Left")
- AnimTurn(hog1, "Right")
- end
-end
-
-function EmitDenseClouds(dir)
- local dif
- if dir == "Left" then
- dif = 10
- else
- dif = -10
- end
- if dir == nil then
- dx, dy = GetGearVelocity(dense)
- if dx < 0 then
- dif = 10
- else
- dif = -10
- end
- end
- AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
- AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
- AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
- AnimInsertStepNext({func = AnimWait, args = {dense, 800}})
- AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
- AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
- AnimInsertStepNext({func = AnimWait, args = {dense, 800}})
- AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
-end
-
-function RestoreNatives(cgi)
- for i = 1, playersNum do
- RestoreHedge(players[i])
- AnimOutOfNowhere(players[i], GetGearPosition(players[i]))
- end
-end
-
-function AnimationSetup()
- SetupCyborgStartAnim()
- SetupPeopleStartAnim()
- SetupEnemyStartAnim()
- AddSkipFunction(startAnim, SkipStartAnim, {})
-end
-
-function SetupCyborgStartAnim()
- table.insert(startAnim, {func = AnimWait, args = {cyborg, 3000}})
- table.insert(startAnim, {func = AnimTurn, args = {cyborg, "Left"}})
- table.insert(startAnim, {func = AnimWait, args = {cyborg, 800}})
- table.insert(startAnim, {func = AnimTurn, args = {cyborg, "Right"}})
- table.insert(startAnim, {func = AnimWait, args = {cyborg, 800}})
- table.insert(startAnim, {func = AnimTurn, args = {cyborg, "Left"}})
- table.insert(startAnim, {func = AnimWait, args = {cyborg, 800}})
- table.insert(startAnim, {func = AnimTeleportGear, args = {cyborg, unpack(cyborgPos[2])}})
- table.insert(startAnim, {func = AnimWait, args = {cyborg, 800}})
- table.insert(startAnim, {func = AnimTurn, args = {cyborg, "Right"}})
- table.insert(startAnim, {func = AnimWait, args = {cyborg, 800}})
- table.insert(startAnim, {func = AnimTurn, args = {cyborg, "Left"}})
- table.insert(startAnim, {func = AnimWait, args = {cyborg, 800}})
- table.insert(startAnim, {func = AnimTeleportGear, args = {cyborg, unpack(cyborgPos[3])}})
- table.insert(startAnim, {func = AnimWait, args = {cyborg, 1800}})
- table.insert(startAnim, {func = AnimTeleportGear, args = {cyborg, unpack(cyborgPos[4])}})
- table.insert(startAnim, {func = AnimWait, args = {cyborg, 800}})
- table.insert(startAnim, {func = AnimSay, args = {cyborg, loc("Everything looks OK..."), SAY_THINK, 2500}})
- table.insert(startAnim, {func = AnimSay, args = {cyborg, loc("This will be fun!"), SAY_THINK, 2500}})
- table.insert(startAnim, {func = AnimJump, args = {cyborg, "high"}})
- table.insert(startAnim, {func = AnimCustomFunction, args = {cyborg, RestoreNatives, {true}}})
- table.insert(startAnim, {func = AnimSay, args = {cyborg, loc("HAHA!"), SAY_SHOUT, 2000}})
- table.insert(startAnim, {func = AnimSwitchHog, args = {players[1]}})
- table.insert(startAnim, {func = AnimDisappear, swh = false, args = {cyborg, unpack(cyborgPos[4])}})
- table.insert(startAnim, {func = HideHedge, swh = false, args = {cyborg}})
-end
-
-function SetupPeopleStartAnim()
- for i = 1, playersNum do
- table.insert(startAnim, {func = AnimTurn, swh = false, args = {players[i], playersAntiDir[i]}})
- end
- table.insert(startAnim, {func = AnimWait, args = {players[1], 800}})
- for i = 1, playersNum do
- table.insert(startAnim, {func = AnimTurn, swh = false, args = {players[i], playersDir[i]}})
- end
- table.insert(startAnim, {func = AnimWait, args = {players[1], 800}})
- table.insert(startAnim, {func = AnimSay, args = {players[1], loc("What is this place?"), SAY_SHOUT, 2500}})
- if m5LeaksDead == 1 then
- table.insert(startAnim, {func = AnimSay, args = {players[1], loc("And how am I alive?!"), SAY_SAY, 3000}})
- end
- table.insert(startAnim, {func = AnimCustomFunction, args = {players[1], CondNeedToTurn, {players[1], players[2]}}})
- table.insert(startAnim, {func = AnimSay, args = {players[2], loc("It must be the cyborgs again!"), SAY_SAY, 4000}})
- table.insert(startAnim, {func = AnimSay, args = {players[3], loc("Looks like the whole world is falling apart!"), SAY_SAY, 6000}})
- table.insert(startAnim, {func = AnimSay, args = {cannibals[1], loc("Look out! We're surrounded by cannibals!"), SAY_SHOUT, 6000}})
- table.insert(startAnim, {func = AnimCustomFunction, args = {players[4], CondNeedToTurn, {players[4], cannibals[1]}}})
- table.insert(startAnim, {func = AnimCustomFunction, args = {players[4], CondNeedToTurn, {players[1], cannibals[1]}}})
- table.insert(startAnim, {func = AnimSay, args = {players[4], loc("Cannibals?! You're the cannibals!"), SAY_SHOUT, 4000}})
- table.insert(startAnim, {func = AnimSay, args = {cannibals[1], loc("WHAT?! You're the ones attacking us!"), SAY_SHOUT, 5000}})
- table.insert(startAnim, {func = AnimSay, args = {players[4], loc("You have kidnapped our whole tribe!"), SAY_SHOUT, 4000}})
- table.insert(startAnim, {func = AnimSay, args = {players[1], loc("You've been assaulting us, we have been just defending ourselves!"), SAY_SHOUT, 8000}})
- table.insert(startAnim, {func = AnimSay, args = {cannibals[1], loc("I can't believe this!"), SAY_SHOUT, 3000}})
- table.insert(startAnim, {func = AnimSay, args = {cannibals[1], loc("Have we ever attacked you first?"), SAY_SHOUT, 5000}})
- table.insert(startAnim, {func = AnimSay, args = {players[4], loc("Yes!"), SAY_SHOUT, 2000}})
- table.insert(startAnim, {func = AnimSay, args = {cannibals[1], loc("When?"), SAY_SHOUT, 2000}})
- table.insert(startAnim, {func = AnimSay, args = {players[4], loc("Uhmm...ok no."), SAY_SHOUT, 2000}})
- table.insert(startAnim, {func = AnimSay, args = {players[1], loc("But you're cannibals. It's what you do."), SAY_SHOUT, 5000}})
- table.insert(startAnim, {func = AnimSay, args = {cannibals[1], loc("Again with the 'cannibals' thing!"), SAY_SHOUT, 4000}})
- table.insert(startAnim, {func = AnimSay, args = {cannibals[1], loc("Where do you get that?!"), SAY_SHOUT, 3000}})
- table.insert(startAnim, {func = AnimSay, args = {players[4], loc("Everyone knows this."), SAY_SHOUT, 2500}})
- table.insert(startAnim, {func = AnimSay, args = {players[1], loc("I didn't until about a month ago."), SAY_SHOUT, 4000}})
- table.insert(startAnim, {func = AnimSay, args = {players[4], loc("Hmmm...actually...I didn't either."), SAY_SHOUT, 4000}})
- table.insert(startAnim, {func = AnimSay, args = {cannibals[1], loc("About a month ago, a cyborg came and told us that you're the cannibals!"), SAY_SHOUT, 8000}})
- table.insert(startAnim, {func = AnimSay, args = {players[1], loc("A cy-what?"), SAY_SHOUT, 2000}})
- table.insert(startAnim, {func = AnimSay, args = {cannibals[1], loc("Cyborg. It's what the aliens call themselves."), SAY_SHOUT, 5000}})
- table.insert(startAnim, {func = AnimSay, args = {cannibals[1], loc("They told us to wear these clothes. They said that this is the newest trend."), SAY_SHOUT, 8000}})
- table.insert(startAnim, {func = AnimSay, args = {players[1], loc("They've been manipulating us all this time!"), SAY_SHOUT, 5000}})
- table.insert(startAnim, {func = AnimSay, args = {cannibals[1], loc("They must be trying to weaken us!"), SAY_SHOUT, 5000}})
- table.insert(startAnim, {func = AnimSay, args = {players[1], loc("We have to unite and defeat those cylergs!"), SAY_SHOUT, 5000}})
- table.insert(startAnim, {func = AnimSay, args = {cannibals[1], loc("We can't let them take over our little island!"), SAY_SHOUT, 5000}})
-end
-
-function RestoreCyborgs(cgi)
- if cyborgsRestored == true then
- return
- end
- for i = 1, cyborgsNum do
- RestoreHedge(cyborgs[i])
- if cgi == true then
- AnimOutOfNowhere(cyborgs[i], unpack(cyborgsPos[i]))
- end
- end
- RestoreHedge(leader)
- AnimOutOfNowhere(leader, unpack(leaderPos))
- cyborgsRestored = true
-end
-
-function SetupEnemyStartAnim()
- local gear
- table.insert(startAnim, {func = AnimCustomFunction, args = {cannibals[1], RestoreCyborgs, {true}}})
- if m8EnemyFled == 1 then
- gear = leader
- else
- gear = cyborgs[2]
- end
- table.insert(startAnim, {func = AnimCustomFunction, args = {players[1], CondNeedToTurn, {players[4], gear}}})
- table.insert(startAnim, {func = AnimCustomFunction, args = {players[1], CondNeedToTurn, {players[1], gear}}})
- table.insert(startAnim, {func = AnimSay, args = {gear, loc("You have finally figured it out!"), SAY_SHOUT, 4500}})
- table.insert(startAnim, {func = AnimSay, args = {gear, loc("You meatbags are pretty slow, you know!"), SAY_SHOUT, 5500}})
- table.insert(startAnim, {func = AnimSay, args = {players[1], loc("Why do you want to take over our island?"), SAY_SHOUT, 5500}})
- table.insert(startAnim, {func = AnimSay, args = {gear, loc("Do you have any idea how valuable grass is?"), SAY_SHOUT, 5500}})
- table.insert(startAnim, {func = AnimSay, args = {gear, loc("This island is the only place left on Earth with grass on it!"), SAY_SHOUT, 7000}})
- table.insert(startAnim, {func = AnimSay, args = {gear, loc("It's worth more than wood!"), SAY_SHOUT, 4000}})
- table.insert(startAnim, {func = AnimSay, args = {gear, loc("That makes it almost invaluable!"), SAY_SHOUT, 4500}})
- table.insert(startAnim, {func = AnimSay, args = {players[1], loc("We have nowhere else to live!"), SAY_SHOUT, 4500}})
- table.insert(startAnim, {func = AnimSay, args = {gear, loc("That's not our problem!"), SAY_SHOUT, 4500}})
- table.insert(startAnim, {func = AnimSay, args = {players[1], loc("We'll give you a problem then!"), SAY_SHOUT, 5000}})
- table.insert(startAnim, {func = AnimSwitchHog, args = {gear}})
-end
-
-function SetupFinalAnim()
- finalAnim = {
- {func = AnimGearWait, args = {cyborg, 1000}},
- {func = AnimSay, args = {cyborg, loc("Nicely done, meatbags!"), SAY_SAY, 3000}},
- {func = AnimSay, args = {cyborg, loc("You have won the game by proving true cooperative skills!"), SAY_SAY, 7000}},
- {func = AnimSay, args = {cyborg, loc("You have proven yourselves worthy!"), SAY_SAY, 4000}},
- {func = AnimSay, args = {players[1], loc("Game? Was this a game to you?!"), SAY_SAY, 4000}},
- {func = AnimSay, args = {cyborg, loc("Well, yes. This was a cyborg television show."), SAY_SAY, 5500}},
- {func = AnimSay, args = {cyborg, loc("It is called 'Hogs of Steel'."), SAY_SAY, 4000}},
- {func = AnimSay, args = {players[1], loc("Are you saying that many of us have died for your entertainment?"), SAY_SAY, 8000}},
- {func = AnimSay, args = {players[1], loc("Our tribe, our beautiful island!"), SAY_SAY, 4000}},
- {func = AnimSay, args = {players[1], loc("All gone...everything!"), SAY_SAY, 3000}},
- {func = AnimSay, args = {cyborg, loc("But the ones alive are stronger in their heart!"), SAY_SAY, 6000}},
- {func = AnimSay, args = {cyborg, loc("Just kidding, none of you have died!"), SAY_SAY, 5000}},
- {func = AnimSay, args = {cyborg, loc("I mean, none of you ceased to live."), SAY_SAY, 5000}},
- {func = AnimSay, args = {cyborg, loc("You'll see what I mean!"), SAY_SAY, 4000}},
- {func = AnimSay, args = {cyborg, loc("They are all waiting back in the village, haha."), SAY_SAY, 7000}},
- {func = AnimSay, args = {players[1], loc("You are playing with our lives here!"), SAY_SAY, 6000}},
- {func = AnimSay, args = {players[1], loc("Do you think you're some kind of god?"), SAY_SAY, 6000}},
- {func = AnimSay, args = {cyborg, loc("Interesting idea, haha!"), SAY_SAY, 2000}},
- {func = AnimSwitchHog, args = {players[1]}},
- {func = AnimWait, args = {players[1], 1}},
- {func = AnimDisappear, swh = false, args = {cyborg, unpack(cyborgPos[4])}},
- {func = HideHedge, swh = false, args = {cyborg}},
- {func = AnimSay, args = {players[1], loc("What a douche!"), SAY_SAY, 2000}},
- }
-end
---------------------------Anim skip functions--------------------------
-function SkipStartAnim()
- RestoreNatives()
- RestoreCyborgs()
- SetGearMessage(CurrentHedgehog, 0)
- AnimSwitchHog(cyborgs[1])
- AnimWait(cyborg, 1)
- AddFunction({func = HideHedge, args = {cyborg}})
-end
-
-function AfterStartAnim()
- ShowMission(loc("The Enemy Of My Enemy"), loc("The Union"), loc("Defeat the cyborgs!"), 1, 0)
- PutWeaponCrates()
- PutHealthCrates()
- TurnTimeLeft = 0
-end
-
-function PutHealthCrates()
- for i = 1, 10 do
- SpawnHealthCrate(0, 0)
- end
-end
-
-function PutWeaponCrates()
- SpawnAmmoCrate(2399, 622, amNapalm, 2)
- SpawnAmmoCrate(2199, -18, amBee, 2)
- SpawnAmmoCrate(2088, 430, amBee, 2)
- SpawnAmmoCrate(237, 20, amMortar, 4)
- SpawnAmmoCrate(312, 1107, amMolotov, 3)
- SpawnAmmoCrate(531, 1123, amWatermelon, 2)
- SpawnAmmoCrate(1253, 1444, amFlamethrower, 5)
- SpawnAmmoCrate(994, 1364, amBaseballBat, 3)
- SpawnAmmoCrate(1104, 1553, amMine, 6)
- SpawnAmmoCrate(2277, 803, amDynamite, 2)
- SpawnAmmoCrate(1106, 184, amRCPlane, 3)
- SpawnAmmoCrate(1333, 28, amSMine, 4)
- SpawnAmmoCrate(90, 279, amAirAttack, 2)
- SpawnAmmoCrate(288, 269, amBee, 2)
- SpawnAmmoCrate(818, 1633, amBaseballBat, 2)
-end
------------------------------Events------------------------------------
-function CheckNativesDead()
- return nativesLeft == 0
-end
-
-function CheckCannibalsDead()
- return cannibalsLeft == 0
-end
-
-function CheckPlayersDead()
- return playersLeft == 0
-end
-
-function CheckCyborgsDead()
- return (cyborgsLeft == 0 and (leader == nil or gearDead[leader] == true))
-end
-
-function DoNativesDead()
- nativesDeadFresh = true
- TurnTimeLeft = 0
-end
-
-function DoCannibalsDead()
- cannibalsDeadFresh = true
- TurnTimeLeft = 0
-end
-
-function DoPlayersDead()
- RemoveEventFunc(CheckNativesDead)
- RemoveEventFunc(CheckCannibalsDead)
- RemoveEventFunc(CheckCyborgsDead)
- playersDeadFresh = true
- TurnTimeLeft = 0
-end
-
-function DoCyborgsDead()
--- RemoveEventFunc(CheckNativesDead)
--- RemoveEventFunc(CheckCannibalsDead)
- cyborgsDeadFresh= true
- TurnTimeLeft = 0
-end
-
-function CheckGearsDead(gearList)
- for i = 1, # gearList do
- if gearDead[gearList[i]] ~= true then
- return false
- end
- end
- return true
-end
-
-function CheckGearDead(gear)
- return gearDead[gear]
-end
-
-function FailedMission()
- RestoreHedge(cyborg)
- AnimOutOfNowhere(cyborg, unpack(cyborgPos[1]))
- if CheckCyborgsDead() then
- AnimSay(cyborg, loc("Hmmm...it's a draw. How unfortunate!"), SAY_THINK, 6000)
- elseif leader ~= nil then
- CondNeedToTurn2(cyborg, leader)
- AddAnim({{func = AnimSay, args = {leader, loc("Yay, we won!"), SAY_SAY, 2000}},
- {func = AnimSay, args = {cyborg, loc("Nice work!"), SAY_SAY, 2000}}})
- else
- CondNeedToTurn2(cyborg, cyborgs[1])
- AddAnim({{func = AnimSay, args = {cyborgs[1], loc("Yay, we won!"), SAY_SAY, 2000}},
- {func = AnimSay, args = {cyborg, loc("Nice work!"), SAY_SAY, 2000}}})
- end
- AddFunction({func = LoseMission, args = {}})
-end
-
-function LoseMission()
- ParseCommand("teamgone " .. loc("Natives"))
- ParseCommand("teamgone " .. loc("Cannibals"))
- ParseCommand("teamgone " .. loc("011101001"))
- TurnTimeLeft = 0
-end
-
-function WonMission()
- RestoreHedge(cyborg)
- CondNeedToTurn2(cyborg, players[1])
- SetupFinalAnim()
- AddAnim(finalAnim)
- AddFunction({func = WinMission, args = {}})
-end
-
-function WinMission()
- if progress and progress<9 then
- SaveCampaignVar("Progress", "9")
- end
- ParseCommand("teamgone " .. loc("011101001"))
- TurnTimeLeft = 0
-end
------------------------------Misc--------------------------------------
-function HideHedge(hedge)
- if hedgeHidden[hedge] ~= true then
- HideHog(hedge)
- hedgeHidden[hedge] = true
- end
-end
-
-function RestoreHedge(hedge)
- if hedgeHidden[hedge] == true then
- RestoreHog(hedge)
- hedgeHidden[hedge] = false
- end
-end
-
-function GetVariables()
- progress = tonumber(GetCampaignVar("Progress"))
- m5DeployedNum = tonumber(GetCampaignVar("M5DeployedNum"))
- m2Choice = tonumber(GetCampaignVar("M2Choice"))
- m5Choice = tonumber(GetCampaignVar("M5Choice"))
- m2DenseDead = tonumber(GetCampaignVar("M2DenseDead"))
- m4DenseDead = tonumber(GetCampaignVar("M4DenseDead"))
- m5DenseDead = tonumber(GetCampaignVar("M5DenseDead"))
- m4LeaksDead = tonumber(GetCampaignVar("M4LeaksDead"))
- m5LeaksDead = tonumber(GetCampaignVar("M5LeaksDead"))
- m4ChiefDead = tonumber(GetCampaignVar("M4ChiefDead"))
- m5ChiefDead = tonumber(GetCampaignVar("M5ChiefDead"))
- m4WaterDead = tonumber(GetCampaignVar("M4WaterDead"))
- m5WaterDead = tonumber(GetCampaignVar("M5WaterDead"))
- m4BuffaloDead = tonumber(GetCampaignVar("M4BuffaloDead"))
- m5BuffaloDead = tonumber(GetCampaignVar("M5BuffaloDead"))
- m5WiseDead = tonumber(GetCampaignVar("M5WiseDead"))
- m5GirlDead = tonumber(GetCampaignVar("M5GirlDead"))
- m8DeployedDead = tonumber(GetCampaignVar("M8DeployedDead"))
- m8PrincessDead = tonumber(GetCampaignVar("M8PrincessDead"))
- m8RamonDead = tonumber(GetCampaignVar("M8RamonDead"))
- m8SpikyDead = tonumber(GetCampaignVar("M8SpikyDead"))
- m8DeployedLeader = tonumber(GetCampaignVar("M8DeployedLeader"))
- m8PrincessLeader = tonumber(GetCampaignVar("M8PrincessLeader"))
- m8EnemyFled = tonumber(GetCampaignVar("M8EnemyFled"))
- m8Scene = tonumber(GetCampaignVar("M8Scene"))
-end
-
-function SetupPlace()
- for i = 1, playersNum do
- HideHedge(players[i])
- end
- for i = 1, cyborgsNum do
- HideHedge(cyborgs[i])
- end
- if leader ~= nil then
- HideHedge(leader)
- end
-end
-
-function SetupEvents()
- AddNewEvent(CheckPlayersDead, {}, DoPlayersDead, {}, 0)
- AddNewEvent(CheckNativesDead, {}, DoNativesDead, {}, 0)
- AddNewEvent(CheckCannibalsDead, {}, DoCannibalsDead, {}, 0)
- AddNewEvent(CheckCyborgsDead, {}, DoCyborgsDead, {}, 0)
-end
-
-function SetupAmmo()
- AddAmmo(cyborgs[1], amClusterBomb, 100)
- AddAmmo(cyborgs[1], amMortar, 100)
- AddAmmo(cyborgs[1], amDynamite, 2)
- AddAmmo(cyborgs[1], amAirAttack, 2)
- AddAmmo(cyborgs[1], amTeleport, 100)
-
- if leader ~= nil then
- AddAmmo(leader, amClusterBomb, 100)
- AddAmmo(leader, amMortar, 100)
- AddAmmo(leader, amDynamite, 100)
- AddAmmo(leader, amAirAttack, 3)
- AddAmmo(leader, amTeleport, 100)
- end
-end
-
-function AddHogs()
- AddTeam(loc("011101001"), 14483456, "ring", "UFO", "Robot", "cm_star")
- cyborg = AddHog(loc("Unit 334a$7%;.*"), 0, 200, "cyborg1")
-
- AddTeam(loc("Natives"), 29439, "Bone", "Island", "HillBilly", "cm_birdy")
- natives[1] = AddHog(nativeNames[leaksNum], 0, 100, nativeHats[leaksNum])
- if m5DeployedNum ~= leaksNum and m8DeployedLeader == 0 then
- natives[2] = AddHog(nativeNames[m5DeployedNum], 0, 100, nativeHats[m5DeployedNum])
- end
- table.insert(natives, AddHog(nativeNames[ramonNum], 0, 100, nativeHats[ramonNum]))
- table.insert(natives, AddHog(nativeNames[spikyNum], 0, 100, nativeHats[spikyNum]))
- if m8PrincessLeader == 0 then
- table.insert(natives, AddHog(loc("Fell From Heaven"), 0, 100, "tiara"))
- end
- nativesNum = #natives
- nativesLeft = nativesNum
- cannibalsLeft = cannibalsNum
- for i = 1, nativesNum do
- table.insert(players, natives[i])
- end
-
- AddTeam(loc("Cannibals"), 29439, "Bone", "Island", "HillBilly", "cm_birdy")
- for i = 1, cannibalsNum do
- cannibals[i] = AddHog(cannibalNames[i], 0, 100, "Zombi")
- table.insert(players, cannibals[i])
- end
- playersNum = #players
- playersLeft = playersNum
-
- AddTeam(loc("Hedge-cogs"), 14483455, "ring", "UFO", "Robot", "cm_star")
- for i = 1, cyborgsNum do
- cyborgs[i] = AddHog(cyborgNames[i], 2, 80, "cyborg2")
- end
-
- if m8EnemyFled == 1 then
- AddTeam(loc("Leader"), 14483455, "ring", "UFO", "Robot", "cm_star")
- if m8Scene == denseScene then
- leader = AddHog(loc("Dense Cloud"), 2, 200, nativeHats[denseNum])
- elseif m8Scene == waterScene then
- leader = AddHog(loc("Fiery Water"), 2, 200, nativeHats[waterNum])
- elseif m8Scene == princessScene then
- leader = AddHog(loc("Fell From Heaven"), 2, 200, "tiara")
- else
- leader = AddHog(loc("Nancy Screw"), 2, 200, "cyborg2")
- end
- end
-
- cyborgsLeft = cyborgsNum
-
- for i = 1, nativesNum do
- AnimSetGearPosition(natives[i], unpack(nativePos[i]))
- AnimTurn(natives[i], nativeDir[i])
- end
- for i = 1, cannibalsNum do
- AnimSetGearPosition(cannibals[i], unpack(cannibalPos[i]))
- AnimTurn(cannibals[i], cannibalDir[i])
- end
- for i = 1, cyborgsNum do
- AnimSetGearPosition(cyborgs[i], unpack(cyborgsPos[i]))
- AnimTurn(cyborgs[i], cyborgsDir[i])
- end
- AnimSetGearPosition(cyborg, unpack(cyborgPos[1]))
- AnimTurn(cyborg, cyborgDir)
- if leader ~= nil then
- AnimSetGearPosition(leader, unpack(leaderPos))
- AnimTurn(leader, leaderDir[i])
- end
-end
-
------------------------------Main Functions----------------------------
-
-function onGameInit()
- Seed = 0
- GameFlags = gfSolidLand
- TurnTime = 60000
- CaseFreq = 0
- MinesNum = 0
- MinesTime = 3000
- Explosives = 0
- Delay = 10
- Map = "Islands"
- Theme = "EarthRise"
- SuddenDeathTurns = 20
-
- GetVariables()
- AnimInit()
- AddHogs()
-end
-
-function onGameStart()
- SetupAmmo()
- SetupPlace()
- AnimationSetup()
- SetupEvents()
- AddAnim(startAnim)
- AddFunction({func = AfterStartAnim, args = {}})
-end
-
-function onGameTick()
- AnimUnWait()
- if ShowAnimation() == false then
- return
- end
- ExecuteAfterAnimations()
- CheckEvents()
-end
-
-function onGearDelete(gear)
- gearDead[gear] = true
- if GetGearType(gear) == gtHedgehog then
- if GetHogTeamName(gear) == loc("Natives") then
- for i = 1, nativesLeft do
- if natives[i] == gear then
- table.remove(natives, i)
- table.remove(players, i)
- nativesLeft = nativesLeft - 1
- playersLeft = playersLeft - 1
- end
- end
- elseif GetHogTeamName(gear) == loc("Cannibals") then
- for i = 1, cannibalsLeft do
- if cannibals[i] == gear then
- table.remove(cannibals, i)
- table.remove(players, nativesLeft + i)
- cannibalsLeft = cannibalsLeft - 1
- playersLeft = playersLeft - 1
- end
- end
- elseif GetHogTeamName(gear) == loc("Hedge-cogs") then
- for i = 1, cyborgsLeft do
- if cyborgs[i] == gear then
- table.remove(cyborgs, i)
- end
- end
- cyborgsLeft = cyborgsLeft - 1
- end
- end
-end
-
-function onAmmoStoreInit()
- SetAmmo(amSkip, 9, 0, 0, 0)
- SetAmmo(amSwitch, 9, 0, 0, 0)
- SetAmmo(amDEagle, 9, 0, 0, 0)
- SetAmmo(amSniperRifle, 9, 0, 0, 0)
- SetAmmo(amBazooka, 8, 0, 0, 0)
- SetAmmo(amGrenade, 7, 0, 0, 0)
- SetAmmo(amFirePunch, 9, 0, 0, 0)
- SetAmmo(amShotgun, 9, 0, 0, 0)
-
- SetAmmo(amParachute, 9, 0, 0, 0)
- SetAmmo(amRope, 9, 0, 0, 0)
- SetAmmo(amPickHammer, 9, 0, 0, 0)
- SetAmmo(amBlowTorch, 9, 0, 0, 0)
-end
-
-function onNewTurn()
- if AnimInProgress() then
- TurnTimeLeft = -1
- return
- end
- if playersDeadFresh then
- playersDeadFresh = false
- FailedMission()
- elseif cyborgsDeadFresh then
- cyborgsDeadFresh = false
- WonMission()
- elseif nativesDeadFresh and GetHogTeamName(CurrentHedgehog) == loc("Cannibals") then
- AnimSay(CurrentHedgehog, loc("Your deaths will be avenged, cannibals!"), SAY_SHOUT, 0)
- nativesDeadFresh = false
- elseif cannibalsDeadFresh and GetHogTeamName(CurrentHedgehog) == loc("Natives") then
- AnimSay(CurrentHedgehog, loc("Your deaths will be avenged, cannibals!"), SAY_SHOUT, 0)
- cannibalsDeadFresh = false
- end
-end
-
-function onPrecise()
- if GameTime > 3000 and AnimInProgress() then
- SetAnimSkip(true)
- end
-end
--- a/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/epil.lua Mon Jul 01 22:28:42 2013 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,433 +0,0 @@
-HedgewarsScriptLoad("/Scripts/Locale.lua")
-HedgewarsScriptLoad("/Scripts/Animate.lua")
-
------------------------------Constants---------------------------------
-leaksNum = 1
-denseNum = 2
-waterNum = 3
-buffaloNum = 4
-chiefNum = 5
-girlNum = 6
-wiseNum = 7
-ramonNum = 8
-spikyNum = 9
-princessNum = 10
-
-denseScene = 1
-princessScene = 2
-waterScene = 3
-cyborgScene = 4
-
-nativeNames = {loc("Leaks A Lot"), loc("Dense Cloud"), loc("Fiery Water"),
- loc("Raging Buffalo"), loc("Righteous Beard"), loc("Fell From Grace"),
- loc("Wise Oak"), loc("Ramon"), loc("Spiky Cheese"),
- loc("Fell From Heaven")
- }
-nativeHats = {"Rambo", "RobinHood", "pirate_jack", "zoo_Bunny", "IndianChief",
- "tiara", "AkuAku", "rasta", "hair_yellow", "tiara"}
-
-nativePosCyborg = {{1900, 508}, {480, 1321}, {2927, 873},
- {1325, 905}, {3190, 1424}, {1442, 857},
- {1134, 1278}, {2881, 853}, {2974, 897},
- {2033, 511}}
-nativeDirCyborg = {"Right", "Right", "Left", "Right", "Right", "Left", "Right", "Right", "Left", "Left"}
-
-nativePosPrincess = {{1930, 508}, {480, 1321}, {2927, 873},
- {1325, 905}, {3190, 1424}, {2033, 511},
- {1134, 1278}, {2881, 853}, {2974, 897},
- {1900, 508}}
-nativeDirPrincess = {"Right", "Right", "Left", "Right", "Right", "Left", "Right", "Right", "Left", "Right"}
-
-nativePosDense = {{1930, 508}, {2285, 772}, {2927, 873},
- {1325, 905}, {3190, 1424}, {1442, 857},
- {1134, 1278}, {480, 1321}, {2974, 897},
- {2033, 511}}
-nativeDirDense = {"Right", "Left", "Left", "Right", "Right", "Left", "Right", "Right", "Left", "Left"}
-
-nativePosWater = {{1900, 508}, {2033, 511}, {2285, 772},
- {1325, 905}, {3190, 1424}, {1442, 857},
- {1134, 1278}, {480, 1321}, {2974, 897},
- {1980, 511}}
-nativeDirWater = {"Right", "Left", "Left", "Right", "Right", "Left", "Right", "Right", "Left", "Left"}
-
-prisonPos = {2285, 772}
-
-brainNum = 1
-corpseNum = 2
-brutalNum = 3
-earNum = 4
-hanniNum = 5
-
-cannibalNames = {loc("Brainiac"), loc("Corpse Thrower"), loc("Brutal Lily"), loc("Ear Sniffer"), loc("Hannibal")}
-cannibalHats = {"Zombi", "AkuAku", "Zombi", "Zombi", "IndianChief"}
-cannibalPos = {{533, 1304}, {1184, 1282}, {1386, 883}, {2854, 834}, {3243, 1415}}
-cannibalDir = {"Left", "Left", "Left", "Right", "Left"}
------------------------------Variables---------------------------------
-natives = {}
-cannibals = {}
-traitor = nil
-crate = nil
-
-startAnim = {}
-
-gearDead = {}
---------------------------Anim skip functions--------------------------
-function SkipStartAnim()
- SetGearMessage(CurrentHedgehog, 0)
- AnimSwitchHog(natives[1])
-end
-
-function AfterStartAnim()
- crate = SpawnHealthCrate(0, 0)
- SetGearMessage(CurrentHedgehog, 0)
- AddNewEvent(CheckCrateTaken, {}, DoCrateTaken, {}, 1)
- TurnTimeLeft = 0
- ShowMission("Epilogue", "That's all folks!", "You have successfully finished the campaign!|If you wish to replay, there are other possible endings, too!|You can practice moving around and using utilities in this mission.|However, it will never end!", 1, 0)
-end
-
----------------------------Events-------------------------------------
-function CheckCrateTaken()
- return gearDead[crate]
-end
-
-function DoCrateTaken()
- crate = SpawnHealthCrate(0, 0)
-end
------------------------------Animations--------------------------------
-function AnimationSetup()
- if m8Scene == cyborgScene then
- SetupAnimCyborg()
- elseif m8Scene == princessScene then
- SetupAnimPrincess()
- elseif m8Scene == waterScene then
- SetupAnimWater()
- else
- SetupAnimDense()
- end
- AddSkipFunction(startAnim, SkipStartAnim, {})
-end
-
-function SetupAnimWater()
- startAnim = {
- {func = AnimWait, args = {natives[1], 3000}},
- {func = AnimCaption, args = {natives[ramonNum], "Back in the village, the two tribes finally started to live in harmony.", 5000}},
- {func = AnimSay, args = {natives[ramonNum], "You got a killer mask there, amigo!", SAY_SAY, 5500}},
- {func = AnimSay, args = {cannibals[brainNum], "Thanks, man! It really means a lot to me.", SAY_SAY, 6000}},
- {func = AnimSay, args = {natives[wiseNum], "So, uhmm, how did you manage to teleport them so far?", SAY_SAY, 8000}},
- {func = AnimSay, args = {cannibals[corpseNum], "It's all about the right carrots, you know.", SAY_SAY, 7000}},
- {func = AnimSay, args = {natives[wiseNum], "Of course! It's all obvious now!", SAY_SAY, 4500}},
- {func = AnimSay, args = {natives[chiefNum], "I can't believe how blind we were...", SAY_SAY, 4500}},
- {func = AnimSay, args = {natives[chiefNum], "Fighting instead of cultivating a beautiful friendship.", SAY_SAY, 8500}},
- {func = AnimSay, args = {cannibals[hanniNum], "One shall not judge one by one's appearance!", SAY_SAY, 7000}},
- {func = AnimSay, args = {natives[chiefNum], "You speak great truth, Hannibal. Here, take a sip!", SAY_SAY, 7500}},
- {func = AnimVisualGear, args = {cannibals[hanniNum], cannibalPos[hanniNum][1], cannibalPos[hanniNum][2], vgtSmoke, 0, true}},
- {func = AnimWait, args = {natives[1], 1000}},
- {func = AnimVisualGear, args = {cannibals[hanniNum], cannibalPos[hanniNum][1], cannibalPos[hanniNum][2], vgtSmoke, 0, true}},
- {func = AnimWait, args = {natives[1], 1000}},
- {func = AnimVisualGear, args = {cannibals[hanniNum], cannibalPos[hanniNum][1], cannibalPos[hanniNum][2], vgtSmoke, 0, true}},
- {func = AnimWait, args = {natives[1], 1000}},
- {func = AnimSay, args = {natives[leaksNum], "It's amazing how quickly our lives can change...", SAY_SAY, 7000}},
- {func = AnimSay, args = {natives[waterNum], "Aye! Fellow! Let me exit this chamber of doom!", SAY_SAY, 7000}},
- {func = AnimTurn, args = {natives[princessNum], "Right"}},
- {func = AnimSay, args = {natives[princessNum], "It's your fault you're there!", SAY_SAY, 5000}},
- {func = AnimTurn, args = {natives[princessNum], "Left"}},
- {func = AnimSay, args = {natives[leaksNum], "I always suspected him!", SAY_SAY, 3000}},
- {func = AnimSay, args = {natives[leaksNum], "Nobody takes walks every day!", SAY_SAY, 4000}},
- {func = AnimSay, args = {natives[princessNum], "I don't know who I can trust anymore.", SAY_SAY, 6000}},
- {func = AnimSay, args = {natives[princessNum], "Everywhere I look, I see hogs walking around...", SAY_SAY, 7000}},
- {func = AnimSay, args = {natives[princessNum], "...and I think they are up to something. Something bad!", SAY_SAY, 8000}},
- {func = AnimMove, args = {natives[leaksNum], "Right", nativePosWater[princessNum][1] - 30, nativePosWater[princessNum][2]}},
- {func = AnimSay, args = {natives[leaksNum], "You can always trust me! I love you!", SAY_SAY, 6000}},
- {func = AnimSay, args = {natives[princessNum], "I know and I'm terribly sorry!", SAY_SAY, 5000}},
- {func = AnimSay, args = {natives[princessNum], "I love Dense Cloud now!", SAY_SAY, 4000}},
- {func = AnimTurn, args = {natives[princessNum], "Right"}},
- {func = AnimMove, args = {natives[denseNum], "Left", nativePosWater[princessNum][1] + 20, nativePosWater[princessNum][2]}},
- {func = AnimSay, args = {natives[denseNum], "Problems, dude? Chillax!", SAY_SAY, 4000}},
- {func = AnimTurn, args = {natives[leaksNum], "Left"}},
- {func = AnimSay, args = {natives[leaksNum], "(T_T)", SAY_SAY, 6000}},
- {func = AnimSwitchHog, args = {natives[leaksNum]}},
- }
-end
-
-function SetupAnimDense()
- startAnim = {
- {func = AnimWait, args = {natives[1], 3000}},
- {func = AnimCaption, args = {natives[ramonNum], "Back in the village, the two tribes finally started to live in harmony.", 5000}},
- {func = AnimSay, args = {natives[ramonNum], "You got a killer mask there, amigo!", SAY_SAY, 5500}},
- {func = AnimSay, args = {cannibals[brainNum], "Thanks, man! It really means a lot to me.", SAY_SAY, 6000}},
- {func = AnimSay, args = {natives[wiseNum], "So, uhmm, how did you manage to teleport them so far?", SAY_SAY, 8000}},
- {func = AnimSay, args = {cannibals[corpseNum], "It's all about the right carrots, you know.", SAY_SAY, 7000}},
- {func = AnimSay, args = {natives[wiseNum], "Of course! It's all obvious now!", SAY_SAY, 4500}},
- {func = AnimSay, args = {natives[chiefNum], "I can't believe how blind we were...", SAY_SAY, 4500}},
- {func = AnimSay, args = {natives[chiefNum], "Fighting instead of cultivating a beautiful friendship.", SAY_SAY, 8500}},
- {func = AnimSay, args = {cannibals[hanniNum], "One shall not judge one by one's appearance!", SAY_SAY, 7000}},
- {func = AnimSay, args = {natives[chiefNum], "You speak great truth, Hannibal. Here, take a sip!", SAY_SAY, 7500}},
- {func = AnimVisualGear, args = {cannibals[hanniNum], cannibalPos[hanniNum][1], cannibalPos[hanniNum][2], vgtSmoke, 0, true}},
- {func = AnimWait, args = {natives[1], 1000}},
- {func = AnimVisualGear, args = {cannibals[hanniNum], cannibalPos[hanniNum][1], cannibalPos[hanniNum][2], vgtSmoke, 0, true}},
- {func = AnimWait, args = {natives[1], 1000}},
- {func = AnimVisualGear, args = {cannibals[hanniNum], cannibalPos[hanniNum][1], cannibalPos[hanniNum][2], vgtSmoke, 0, true}},
- {func = AnimWait, args = {natives[1], 1000}},
- {func = AnimSay, args = {natives[waterNum], "...And then I took a stroll...", SAY_SAY, 4000}},
- {func = AnimSay, args = {natives[leaksNum], "It's amazing how quickly our lives can change...", SAY_SAY, 7000}},
- {func = AnimSay, args = {natives[denseNum], "Dude, let me out!", SAY_SAY, 3000}},
- {func = AnimSay, args = {natives[denseNum], "I already said I'm sorry!", SAY_SAY, 4000}},
- {func = AnimTurn, args = {natives[princessNum], "Right"}},
- {func = AnimSay, args = {natives[princessNum], "Traitors don't get to shout around here!", SAY_SAY, 7000}},
- {func = AnimTurn, args = {natives[princessNum], "Left"}},
- {func = AnimSay, args = {natives[leaksNum], "I still can't believe he sold us out like that.", SAY_SAY, 8000}},
- {func = AnimSay, args = {natives[princessNum], "I don't know who I can trust anymore.", SAY_SAY, 6000}},
- {func = AnimMove, args = {natives[leaksNum], "Right", nativePosDense[princessNum][1] - 30, nativePosDense[princessNum][2]}},
- {func = AnimSay, args = {natives[leaksNum], "You can always trust me!", SAY_SAY, 4000}},
- {func = AnimSay, args = {natives[princessNum], "I know, my hero!", SAY_SAY, 3000}},
- {func = AnimSay, args = {natives[princessNum], "...xoxo...", SAY_SAY, 2000}},
- {func = AnimSwitchHog, args = {natives[leaksNum]}},
- }
-end
-
-function SetupAnimCyborg()
- startAnim = {
- {func = AnimWait, args = {natives[1], 3000}},
- {func = AnimCaption, args = {natives[denseNum], "Back in the village, the two tribes finally started to live in harmony.", 5000}},
- {func = AnimSay, args = {natives[denseNum], "Dude, that outfit is so kool!", SAY_SAY, 4500}},
- {func = AnimSay, args = {cannibals[brainNum], "Thanks, dude! It really means a lot to me.", SAY_SAY, 6000}},
- {func = AnimSay, args = {natives[wiseNum], "So, uhmm, how did you manage to teleport them so far?", SAY_SAY, 8000}},
- {func = AnimSay, args = {cannibals[corpseNum], "It's all about the right carrots, you know.", SAY_SAY, 7000}},
- {func = AnimSay, args = {natives[wiseNum], "Of course! It's all obvious now!", SAY_SAY, 4500}},
- {func = AnimSay, args = {natives[chiefNum], "I can't believe how blind we were...", SAY_SAY, 4500}},
- {func = AnimSay, args = {natives[chiefNum], "Fighting instead of cultivating a beautiful friendship.", SAY_SAY, 8500}},
- {func = AnimSay, args = {cannibals[hanniNum], "One shall not judge one by one's appearance!", SAY_SAY, 7000}},
- {func = AnimSay, args = {natives[chiefNum], "You speak great truth, Hannibal. Here, take a sip!", SAY_SAY, 7500}},
- {func = AnimVisualGear, args = {cannibals[hanniNum], cannibalPos[hanniNum][1], cannibalPos[hanniNum][2], vgtSmoke, 0, true}},
- {func = AnimWait, args = {natives[1], 1000}},
- {func = AnimVisualGear, args = {cannibals[hanniNum], cannibalPos[hanniNum][1], cannibalPos[hanniNum][2], vgtSmoke, 0, true}},
- {func = AnimWait, args = {natives[1], 1000}},
- {func = AnimVisualGear, args = {cannibals[hanniNum], cannibalPos[hanniNum][1], cannibalPos[hanniNum][2], vgtSmoke, 0, true}},
- {func = AnimWait, args = {natives[1], 1000}},
- {func = AnimSay, args = {natives[waterNum], "...And then I took a stroll...", SAY_SAY, 4000}},
- {func = AnimSay, args = {natives[leaksNum], "I'm glad this is over!", SAY_SAY, 4000}},
- {func = AnimMove, args = {natives[princessNum], "Right", nativePosCyborg[princessNum][1] + 30, nativePosCyborg[princessNum][2]}},
- {func = AnimSay, args = {natives[princessNum], "I was so scared.", SAY_SAY, 2500}},
- {func = AnimMove, args = {natives[leaksNum], "Right", nativePosCyborg[princessNum][1], nativePosCyborg[princessNum][2]}},
- {func = AnimSay, args = {natives[leaksNum], "You have nothing to be afraid of now.", SAY_SAY, 6000}},
- {func = AnimSay, args = {natives[leaksNum], "I'll protect you!", SAY_SAY, 3000}},
- {func = AnimTurn, args = {natives[princessNum], "Left"}},
- {func = AnimSay, args = {natives[princessNum], "You're so brave...I feel safe with you.", SAY_SAY, 6500}},
- {func = AnimSay, args = {natives[princessNum], "I think I love you!", SAY_SAY, 3500}},
- {func = AnimSay, args = {natives[leaksNum], "I...like being with you too.", SAY_SAY, 4500}},
- }
-end
-
-function SetupAnimPrincess()
- startAnim = {
- {func = AnimWait, args = {natives[1], 3000}},
- {func = AnimCaption, args = {natives[denseNum], "Back in the village, the two tribes finally started to live in harmony.", 5000}},
- {func = AnimSay, args = {natives[denseNum], "Dude, that outfit is so kool!", SAY_SAY, 4500}},
- {func = AnimSay, args = {cannibals[brainNum], "Thanks, dude! It really means a lot to me.", SAY_SAY, 6000}},
- {func = AnimSay, args = {natives[wiseNum], "So, uhmm, how did you manage to teleport them so far?", SAY_SAY, 8000}},
- {func = AnimSay, args = {cannibals[corpseNum], "It's all about the right carrots, you know.", SAY_SAY, 7000}},
- {func = AnimSay, args = {natives[wiseNum], "Of course! It's all obvious now!", SAY_SAY, 4500}},
- {func = AnimSay, args = {natives[chiefNum], "I can't believe how blind we were...", SAY_SAY, 4500}},
- {func = AnimSay, args = {natives[chiefNum], "Fighting instead of cultivating a beautiful friendship.", SAY_SAY, 8500}},
- {func = AnimSay, args = {cannibals[hanniNum], "One shall not judge one by one's appearance!", SAY_SAY, 7000}},
- {func = AnimSay, args = {natives[chiefNum], "You speak great truth, Hannibal. Here, take a sip!", SAY_SAY, 7500}},
- {func = AnimVisualGear, args = {cannibals[hanniNum], cannibalPos[hanniNum][1], cannibalPos[hanniNum][2], vgtSmoke, 0, true}},
- {func = AnimWait, args = {natives[1], 1000}},
- {func = AnimVisualGear, args = {cannibals[hanniNum], cannibalPos[hanniNum][1], cannibalPos[hanniNum][2], vgtSmoke, 0, true}},
- {func = AnimWait, args = {natives[1], 1000}},
- {func = AnimVisualGear, args = {cannibals[hanniNum], cannibalPos[hanniNum][1], cannibalPos[hanniNum][2], vgtSmoke, 0, true}},
- {func = AnimWait, args = {natives[1], 1000}},
- {func = AnimSay, args = {natives[buffaloNum], "So I shook my fist in the air!", SAY_SAY, 5000}},
- {func = AnimSay, args = {cannibals[brutalNum], "Well that was an unnecessary act of violence.", SAY_SAY, 7000}},
- {func = AnimSay, args = {natives[waterNum], "...And then I took a stroll...", SAY_SAY, 4000}},
- {func = AnimSay, args = {natives[leaksNum], "I'm glad this is over!", SAY_SAY, 4000}},
- {func = AnimSay, args = {natives[girlNum], "I still can't believe you forgave her!", SAY_SAY, 6000}},
- {func = AnimSay, args = {natives[girlNum], "She endangered the whole tribe!", SAY_SAY, 5000}},
- {func = AnimSay, args = {natives[leaksNum], "It wasn't her fault!", SAY_SAY, 4000}},
- {func = AnimSay, args = {natives[leaksNum], "We oppressed her, the only woman in the tribe!", SAY_SAY, 7000}},
- {func = AnimSay, args = {natives[girlNum], "The only woman, huh?", SAY_SAY, 4000}},
- {func = AnimSay, args = {natives[girlNum], "Then what am I?", SAY_SAY, 4000}},
- {func = AnimSay, args = {natives[leaksNum], "Of course, but you're...special.", SAY_SAY, 5000}},
- {func = AnimSay, args = {natives[girlNum], "Sure!", SAY_SAY, 2000}},
- {func = AnimTurn, args = {natives[leaksNum], "Left"}},
- {func = AnimSay, args = {natives[leaksNum], "We're terribly sorry!", SAY_SAY, 4000}},
- {func = AnimSay, args = {natives[princessNum], "I don't know if I can forget what you've done!", SAY_SAY, 7000}},
- {func = AnimTurn, args = {natives[princessNum], "Left"}},
- {func = AnimMove, args = {natives[princessNum], "Left", nativePosPrincess[princessNum][1] - 10, nativePosPrincess[princessNum][2]}},
- {func = AnimSwitchHog, args = {natives[leaksNum]}}
- }
-end
------------------------------Misc--------------------------------------
-function GetVariables()
- m8Scene = tonumber(GetCampaignVar("M8Scene"))
-end
-
-function AddHogs()
- AddTeam(loc("Natives"), 29439, "Bone", "Island", "HillBilly", "cm_birdy")
- for i = 1, 5 do
- natives[i] = AddHog(nativeNames[i], 0, 100, nativeHats[i])
- end
-
- AddTeam(loc("More Natives"), 29439, "Bone", "Island", "HillBilly", "cm_birdy")
- for i = 6, 10 do
- natives[i] = AddHog(nativeNames[i], 0, 100, nativeHats[i])
- end
-
- AddTeam(loc("Cannibals"), 29439, "Bone", "Island", "HillBilly", "cm_birdy")
- for i = 1, 5 do
- cannibals[i] = AddHog(cannibalNames[i], 0, 100, cannibalHats[i])
- end
-
- if m8Scene == denseScene or m8Scene == waterScene then
- AddTeam(loc("Traitors"), 29439, "Bone", "Island", "HillBilly", "cm_birdy")
- if m8Scene == denseScene then
- DeleteGear(natives[2])
- natives[2] = AddHog(nativeNames[2], 0, 100, nativeHats[2])
- else
- DeleteGear(natives[3])
- natives[3] = AddHog(nativeNames[3], 0, 100, nativeHats[3])
- end
- end
-
- SetGearPositions()
-end
-
-function SetGearPositions()
- if m8Scene == cyborgScene then
- for i = 1, 10 do
- AnimSetGearPosition(natives[i], unpack(nativePosCyborg[i]))
- AnimTurn(natives[i], nativeDirCyborg[i])
- end
- elseif m8Scene == waterScene then
- for i = 1, 10 do
- AnimSetGearPosition(natives[i], unpack(nativePosWater[i]))
- AnimTurn(natives[i], nativeDirWater[i])
- end
- elseif m8Scene == denseScene then
- for i = 1, 10 do
- AnimSetGearPosition(natives[i], unpack(nativePosDense[i]))
- AnimTurn(natives[i], nativeDirDense[i])
- end
- else
- for i = 1, 10 do
- AnimSetGearPosition(natives[i], unpack(nativePosPrincess[i]))
- AnimTurn(natives[i], nativeDirPrincess[i])
- end
- end
-
- for i = 1, 5 do
- AnimSetGearPosition(cannibals[i], unpack(cannibalPos[i]))
- AnimTurn(cannibals[i], cannibalDir[i])
- end
-end
-
-function SetupPlace()
- if m8Scene == denseScene or m8Scene == waterScene then
- PlaceGirder(2296, 798, 4)
- PlaceGirder(2296, 700, 4)
- PlaceGirder(2225, 750, 2)
- PlaceGirder(2245, 750, 2)
- PlaceGirder(2265, 750, 2)
- PlaceGirder(2305, 750, 2)
- PlaceGirder(2345, 750, 2)
- PlaceGirder(2365, 750, 2)
- end
- if m8Scene == denseScene then
- traitor = natives[denseNum]
- elseif m8Scene == waterScene then
- traitor = natives[waterNum]
- end
-end
------------------------------Main Functions----------------------------
-function onGameInit()
- Seed = 1
- GameFlags = gfOneClanMode
- TurnTime = 60000
- CaseFreq = 0
- MinesNum = 0
- MinesTime = 3000
- Explosives = 0
- Delay = 10
- Map = "Hogville"
- Theme = "Nature"
- SuddenDeathTurns = 3000
-
- GetVariables()
- AddHogs()
- AnimInit()
-end
-
-function onGameStart()
- SetupPlace()
- AnimationSetup()
- AddAnim(startAnim)
- AddFunction({func = AfterStartAnim, args = {}})
-end
-
-function onGameTick()
- AnimUnWait()
- if ShowAnimation() == false then
- return
- end
- ExecuteAfterAnimations()
- CheckEvents()
-end
-
-function onGearDelete(gear)
- gearDead[gear] = true
-end
-
-function onAmmoStoreInit()
- SetAmmo(amAirStrike, 9, 0, 0, 0)
- SetAmmo(amBaseballBat, 9, 0, 0, 0)
- SetAmmo(amBazooka, 9, 0, 0, 0)
- SetAmmo(amBlowTorch, 9, 0, 0, 0)
- SetAmmo(amClusterBomb,9, 0, 0, 0)
- SetAmmo(amDEagle, 9, 0, 0, 0)
- SetAmmo(amDrill, 9, 0, 0, 4)
- SetAmmo(amDynamite, 9, 0, 0, 3)
- SetAmmo(amFirePunch, 9, 0, 0, 0)
- SetAmmo(amFlamethrower, 9, 0, 0, 3)
- SetAmmo(amGirder, 9, 0, 0, 0)
- SetAmmo(amGrenade, 9, 0, 0, 0)
- SetAmmo(amHammer, 9, 0, 0, 0)
- SetAmmo(amJetpack, 9, 0, 0, 0)
- SetAmmo(amLandGun, 9, 0, 0, 0)
- SetAmmo(amLowGravity, 9, 0, 0, 2)
- SetAmmo(amMine, 9, 0, 0, 2)
- SetAmmo(amMolotov, 9, 0, 0, 3)
- SetAmmo(amMortar, 9, 0, 0, 4)
- SetAmmo(amNapalm, 9, 0, 0, 4)
- SetAmmo(amParachute, 9, 0, 0, 0)
- SetAmmo(amPickHammer, 9, 0, 0, 0)
- SetAmmo(amPortalGun, 9, 0, 0, 0)
- SetAmmo(amRope, 9, 0, 0, 0)
- SetAmmo(amRCPlane, 9, 0, 0, 0)
- SetAmmo(amSkip, 9, 0, 0, 0)
- SetAmmo(amShotgun, 9, 0, 0, 0)
- SetAmmo(amSMine, 9, 0, 0, 2)
- SetAmmo(amSniperRifle, 9, 0, 0, 0)
- SetAmmo(amSnowball, 9, 0, 0, 0)
- SetAmmo(amSwitch, 9, 0, 0, 0)
- SetAmmo(amTeleport, 9, 0, 0, 0)
- SetAmmo(amWatermelon, 9, 0, 0, 0)
- SetAmmo(amWhip, 9, 0, 0, 0)
-end
-
-function onNewTurn()
- if AnimInProgress() then
- TurnTimeLeft = -1
- return
- end
- if CurrentHedgehog == traitor then
- TurnTimeLeft = 0
- else
- TurnTimeLeft = -1
- end
-end
-
-function onPrecise()
- if GameTime > 2500 then
- SetAnimSkip(true)
- end
-end
--- a/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/family.lua Mon Jul 01 22:28:42 2013 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,569 +0,0 @@
-HedgewarsScriptLoad("/Scripts/Locale.lua")
-HedgewarsScriptLoad("/Scripts/Animate.lua")
-
------------------------------Map--------------------------------------
-local map =
-{
- "\255\242\4\218\132\0\53\4\253\0\0\53\4\253\132\0\102\5\92\0\0\102\5\92\132\0\106\5\205\0\0\106\5\205\132\1\1\6\37\0",
- "\1\1\6\37\132\1\124\6\160\0\1\113\6\160\132\2\157\6\111\0\2\164\6\107\132\2\252\6\178\0\2\252\6\178\132\3\224\4\179\0",
- "\3\224\4\179\132\3\38\2\209\0\3\38\2\209\132\4\109\3\179\0\4\109\3\179\132\5\124\3\172\0\5\128\3\172\132\6\69\4\239\0",
- "\6\69\4\239\132\7\175\4\32\0\7\172\4\46\132\8\116\5\18\0\3\38\2\213\132\3\41\1\244\0\3\41\1\244\132\3\94\2\245\0",
- "\8\127\5\8\132\8\127\0\14\0\8\127\0\14\132\8\194\5\29\0\8\194\5\29\132\9\36\5\82\0\9\29\5\75\132\9\180\5\103\0",
- "\9\194\5\92\132\10\51\6\5\0\10\51\6\5\132\10\216\5\152\0\10\227\5\145\132\11\189\5\212\0\11\189\5\212\132\12\91\5\131\0",
- "\12\91\5\131\132\12\253\5\191\0\12\253\5\191\132\13\149\5\106\0\13\149\5\106\132\16\11\5\106\0\14\19\5\110\132\14\16\4\236\0",
- "\14\16\4\236\132\15\66\4\236\0\15\66\4\236\132\15\66\5\110\0\14\79\4\194\132\15\6\4\194\0\14\255\4\176\132\14\255\4\49\0",
- "\14\255\4\49\132\14\76\4\53\0\14\76\4\53\132\14\76\4\201\0\14\125\4\74\128\14\128\4\187\0\14\188\4\77\128\14\185\4\179\0",
- "\14\111\4\39\129\14\76\3\252\0\14\72\3\249\129\14\72\3\147\0\14\72\3\147\129\14\97\3\235\0\14\97\3\235\129\14\146\4\28\0",
- "\14\202\4\28\129\14\248\3\238\0\14\248\3\238\129\15\17\3\133\0\15\17\3\133\129\15\27\3\235\0\15\27\3\235\129\14\230\4\49\0",
- "\1\124\6\220\130\1\244\7\13\0\1\244\7\13\130\2\104\6\206\0\2\100\6\206\130\2\30\6\178\0\2\12\6\181\130\1\135\6\213\0",
- "\3\172\7\136\130\15\41\7\136\0\15\41\7\136\130\15\41\7\62\0\15\41\7\62\130\3\175\7\52\0\3\175\7\52\130\3\126\6\206\0",
- "\3\126\6\206\130\3\122\7\133\0\3\122\7\133\130\3\186\7\136\0\8\123\7\94\136\9\173\7\101\0\8\88\7\66\130\8\88\7\119\0",
- "\9\212\7\69\130\9\212\7\126\0\8\155\0\14\133\8\151\5\11\0\8\190\2\160\131\8\194\5\1\0\14\83\3\235\131\14\114\4\21\0",
- "\15\10\3\196\131\15\10\3\235\0\15\10\3\235\131\14\220\4\32\0\14\65\5\47\137\15\20\5\36\0\15\41\5\82\132\15\41\5\82\0",
- "\3\94\3\17\138\4\137\5\124\0\3\221\3\119\138\5\57\4\250\0\4\102\4\67\160\5\26\4\74\0\4\113\5\36\161\5\142\4\222\0",
- "\4\42\5\216\169\9\89\6\26\0\6\100\5\22\145\8\134\5\64\0\6\255\4\197\140\7\161\4\120\0\7\214\4\204\146\7\214\4\204\0",
- "\10\55\6\97\147\11\13\5\247\0\11\59\6\26\146\11\224\6\30\0\12\95\6\16\153\14\55\6\90\0\13\173\5\226\153\15\196\5\212\0",
- "\15\172\7\91\152\15\165\5\230\0\15\235\7\221\142\255\238\7\207\0\14\248\6\188\152\3\217\6\178\0\3\112\6\83\143\3\31\7\101\0",
- "\3\73\7\143\140\3\73\7\143\0\15\62\7\13\140\15\62\7\13\0\15\101\7\157\140\15\101\7\157\0\2\181\6\220\141\1\205\7\108\0",
- "\2\86\6\160\137\2\150\6\128\0\2\26\6\153\134\1\96\6\195\0\1\82\6\241\136\1\226\7\59\0\2\157\7\98\155\2\157\7\98\0",
- "\1\64\7\80\149\255\249\7\27\0\1\4\6\174\148\0\25\6\86\0\0\211\6\58\139\0\7\5\219\0\0\35\5\159\142\0\4\5\47\0",
- "\8\123\0\14\199\8\187\0\11\0\16\14\5\99\199\16\14\7\245\0\255\235\4\218\199\255\238\8\25\0\8\67\2\72\202\8\208\2\72\0",
- "\8\141\1\251\202\8\141\0\74\0\8\201\2\143\195\8\204\4\49\0\8\84\2\185\205\8\204\2\188\0\8\99\2\230\205\8\187\2\230\0",
- "\8\165\3\41\131\8\144\3\3\0\8\144\3\3\131\8\60\2\248\0\8\60\2\248\131\7\252\3\59\0\7\252\3\59\131\8\137\3\31\0",
- "\8\56\3\20\131\8\102\3\20\0\8\60\3\13\194\8\60\3\13\0\8\60\3\3\128\8\60\3\31\0\7\238\3\66\128\7\214\3\84\0",
- "\7\217\3\87\128\7\217\3\98\0\7\217\3\87\128\7\200\3\91\0\6\209\4\70\208\8\18\4\95\0\0\11\4\225\131\0\0\8\21\0",
- "\15\224\5\99\131\15\245\7\252\0\15\242\5\191\192\15\196\6\33\0\15\196\6\33\192\15\245\6\209\0\15\245\6\209\192\15\193\7\115\0",
- "\15\193\7\115\192\15\235\8\18\0\15\249\5\223\196\15\217\6\40\0\15\217\6\40\196\16\4\6\188\0\15\245\6\16\196\16\21\7\77\0",
- "\16\0\6\245\196\15\214\7\112\0\15\207\7\129\196\16\0\8\4\0\15\245\7\80\196\16\4\7\207\0\15\221\5\85\196\16\11\5\184\0",
-}
---------------------------------------------Constants------------------------------------
-choiceAccepted = 1
-choiceRefused = 2
-choiceAttacked = 3
-
-choiceEliminate = 1
-choiceSpare = 2
-
-leaksNum = 1
-denseNum = 2
-waterNum = 3
-buffaloNum = 4
-chiefNum = 5
-girlNum = 6
-wiseNum = 7
-
-nativeNames = {loc("Leaks A Lot"), loc("Dense Cloud"), loc("Fiery Water"),
- loc("Raging Buffalo"), loc("Righteous Beard"), loc("Fell From Grace"),
- loc("Wise Oak"), loc("Ramon"), loc("Spiky Cheese")
- }
-
-nativeUnNames = {loc("Zork"), loc("Steve"), loc("Jack"),
- loc("Lee"), loc("Elmo"), loc("Rachel"),
- loc("Muriel")}
-
-nativeHats = {"Rambo", "RobinHood", "pirate_jack", "zoo_Bunny", "IndianChief",
- "tiara", "AkuAku", "rasta", "hair_yellow"}
-
-nativePos = {{110, 1310}, {984, 1907}, {1040, 1907}}
-nativePos2 = {196, 1499}
-
-cyborgNames = {loc("Unit 0x0007"), loc("Hogminator"), loc("Carol"),
- loc("Blender"), loc("Elderbot"), loc("Fiery Water")}
-cyborgsDif = {2, 2, 2, 2, 2, 1}
-cyborgsHealth = {45, 45, 45, 40, 40, 20}
-cyborgPos = {945, 1216}
-cyborgsNum = 6
-cyborgsPos = {{2243, 1043}, {3588, 1227}, {2781, 1388},
- {3749, 1040}, {2475, 1338}, {3853, 881}}
-cyborgsDir = {"Left", "Left", "Left", "Left", "Left", "Right"}
-
-princessPos = {3737, 1181}
-crateConsts = {}
-reactions = {}
-
-nativeMidPos = {1991, 841}
-cyborgMidPos = {2109, 726}
-nativeMidPos2 = {2250, 1071}
------------------------------Variables---------------------------------
-natives = {}
-native = nil
-
-cyborgs = {}
-cyborg = nil
-
-gearDead = {}
-hedgeHidden = {}
-
-startAnim = {}
-midAnim = {}
-
-freshDead = nil
-crates = {}
-cratesNum = 0
------------------------------Animations--------------------------------
-function EmitDenseClouds(dir)
- local dif
- if dir == "Left" then
- dif = 10
- else
- dif = -10
- end
- AnimInsertStepNext({func = AnimVisualGear, args = {natives[1], GetX(natives[1]) + dif, GetY(natives[1]) + dif, vgtSteam, 0, true}, swh = false})
- AnimInsertStepNext({func = AnimVisualGear, args = {natives[1], GetX(natives[1]) + dif, GetY(natives[1]) + dif, vgtSteam, 0, true}, swh = false})
- AnimInsertStepNext({func = AnimVisualGear, args = {natives[1], GetX(natives[1]) + dif, GetY(natives[1]) + dif, vgtSteam, 0, true}, swh = false})
- AnimInsertStepNext({func = AnimWait, args = {natives[1], 800}})
- AnimInsertStepNext({func = AnimVisualGear, args = {natives[1], GetX(natives[1]) + dif, GetY(natives[1]) + dif, vgtSteam, 0, true}, swh = false})
- AnimInsertStepNext({func = AnimVisualGear, args = {natives[1], GetX(natives[1]) + dif, GetY(natives[1]) + dif, vgtSteam, 0, true}, swh = false})
- AnimInsertStepNext({func = AnimWait, args = {natives[1], 800}})
- AnimInsertStepNext({func = AnimVisualGear, args = {natives[1], GetX(natives[1]) + dif, GetY(natives[1]) + dif, vgtSteam, 0, true}, swh = false})
-end
-
-function AnimationSetup()
- table.insert(startAnim, {func = AnimWait, args = {natives[1], 4000}})
- table.insert(startAnim, {func = AnimMove, args = {natives[1], "Right", unpack(nativePos2)}})
- if m5DeployedNum == leaksNum then
- table.insert(startAnim, {func = AnimSay, args = {natives[1], loc("Those aliens are destroying the island!"), SAY_THINK, 5000}})
- elseif m5DeployedNum == denseNum then
- table.insert(startAnim, {func = AnimSay, args = {natives[1], loc("Dude, all the plants are gone!"), SAY_THINK, 3500}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], loc("What am I gonna...eat, yo?"), SAY_THINK, 3500}})
- elseif m5DeployedNum == girlNum then
- table.insert(startAnim, {func = AnimSay, args = {natives[1], loc("Fell From Heaven is the best! Fell From Heaven is the greatest!"), SAY_THINK, 7000}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], loc("Yuck! I bet they'll keep worshipping her even after I save the village!"), SAY_THINK, 7500}})
- elseif m5DeployedNum == chiefNum then
- table.insert(startAnim, {func = AnimSay, args = {natives[1], loc("I'm getting old for this!"), SAY_THINK, 4000}})
- elseif m5DeployedNum == waterNum then
- table.insert(startAnim, {func = AnimSay, args = {natives[1], loc("I'm getting thirsty..."), SAY_THINK, 3000}})
- elseif m5DeployedNum == buffaloNum then
- table.insert(startAnim, {func = AnimSay, args = {natives[1], loc("I wonder why I'm so angry all the time..."), SAY_THINK, 6000}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], loc("It must be a childhood trauma..."), SAY_THINK, 4000}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], loc("Just wait till I get my hands on that trauma! ARGH!"), SAY_THINK, 6500}})
- elseif m5DeployedNum == wiseNum then
- table.insert(startAnim, {func = AnimSay, args = {natives[1], loc("I could just teleport myself there..."), SAY_THINK, 4500}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], loc("It's a shame, I forgot how to do that!"), SAY_THINK, 4500}})
- end
- table.insert(startAnim, {func = AnimCustomFunction, args = {natives[1], RestoreHedge, {cyborg}}})
- table.insert(startAnim, {func = AnimOutOfNowhere, args = {cyborg, unpack(cyborgPos)}})
- table.insert(startAnim, {func = AnimTurn, args = {cyborg, "Left"}})
- table.insert(startAnim, {func = AnimTurn, args = {natives[2], "Left"}})
- table.insert(startAnim, {func = AnimTurn, args = {natives[3], "Left"}})
- table.insert(startAnim, {func = AnimSay, args = {cyborg, loc("Hello again, ") .. nativeUnNames[m5DeployedNum] .. "!", SAY_SAY, 2500}})
- table.insert(startAnim, {func = AnimSay, args = {cyborg, loc("I just found out that they have captured your princess!"), SAY_SAY, 7000}})
- if m5DeployedNum == girlNum then
- table.insert(startAnim, {func = AnimSay, args = {natives[1], loc("Of course I have to save her. What did I expect?!"), SAY_SAY, 7000}})
- elseif m5DeployedNum == denseNum then
- table.insert(startAnim, {func = AnimCustomFunction, args = {natives[1], EmitDenseClouds, {"Right"}}})
- end
- table.insert(startAnim, {func = AnimSay, args = {cyborg, loc("She's behind that tall thingy."), SAY_SAY, 5000}})
- table.insert(startAnim, {func = FollowGear, swh = false, args = {princess}})
- table.insert(startAnim, {func = AnimWait, swh = false, args = {princess, 1000}})
- table.insert(startAnim, {func = FollowGear, swh = false, args = {cyborg}})
- table.insert(startAnim, {func = AnimSay, args = {cyborg, loc("I'm here to help you rescue her."), SAY_SAY, 5000}})
- table.insert(startAnim, {func = AnimSay, args = {natives[2], loc("Yo, dude, we're here, too!"), SAY_SHOUT, 4000}})
- table.insert(startAnim, {func = AnimSay, args = {natives[3], loc("We were trying to save her and we got lost."), SAY_SHOUT, 6000}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], loc("That's typical of you!"), SAY_SAY, 3000}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], loc("Why are you helping us, uhm...?"), SAY_SAY, 3000}})
- table.insert(startAnim, {func = AnimSay, args = {cyborg, loc("Call me Beep! Well, 'cause I'm such a nice...person!"), SAY_SAY, 2500}})
- table.insert(startAnim, {func = AnimDisappear, args = {cyborg, unpack(cyborgPos)}})
- table.insert(startAnim, {func = AnimSwitchHog, args = {natives[1]}})
- table.insert(startAnim, {func = AnimWait, args = {natives[1], 1}})
- AddSkipFunction(startAnim, SkipStartAnim, {})
-
- table.insert(midAnim, {func = AnimCustomFunction, args = {natives[1], RestoreHedge, {cyborg}}})
- table.insert(midAnim, {func = AnimOutOfNowhere, args = {cyborg, unpack(cyborgMidPos)}})
- table.insert(midAnim, {func = AnimTurn, args = {cyborg, "Left"}})
- table.insert(midAnim, {func = AnimTeleportGear, args = {natives[1], unpack(nativeMidPos)}})
- table.insert(midAnim, {func = AnimSay, args = {cyborg, loc("Here, let me help you save her!"), SAY_SAY, 5000}})
- table.insert(midAnim, {func = AnimSay, args = {natives[1], loc("Thanks!"), SAY_SAY, 2000}})
- table.insert(midAnim, {func = AnimTeleportGear, args = {natives[1], unpack(nativeMidPos2)}})
- table.insert(midAnim, {func = AnimSay, args = {natives[1], loc("Why can't he just let her go?!"), SAY_THINK, 5000}})
- AddSkipFunction(midAnim, SkipMidAnim, {})
-end
-
---------------------------Anim skip functions--------------------------
-function AfterMidAnim()
- HideHedge(cyborg)
- SetupPlace3()
- SetGearMessage(natives[1], 0)
- AddNewEvent(CheckPrincessFreed, {}, DoPrincessFreed, {}, 0)
- TurnTimeLeft = 0
- ShowMission(loc("Family Reunion"), loc("Salvation"), loc("Get your teammates out of their natural prison and save the princess!|Hint: Drilling holes should solve everything.|Hint: It might be a good idea to place a girder before starting to drill. Just saying.|Hint: All your hedgehogs need to be above the marked height!|Hint: Leaks A Lot needs to get really close to the princess!"), 1, 7000)
- vCirc = AddVisualGear(0,0,vgtCircle,0,true)
- SetVisualGearValues(vCirc, 2625, 1500, 100, 255, 1, 10, 0, 120, 3, 0xff00ffff)
-end
-
-function SkipMidAnim()
- AnimTeleportGear(natives[1], unpack(nativeMidPos2))
- SkipStartAnim()
-end
-
-function SetupPlace3()
- SpawnUtilityCrate(2086, 1887, amRope, 1)
- SpawnUtilityCrate(2147, 728, amBlowTorch, 2)
- SpawnUtilityCrate(2778, 1372, amPickHammer, 3)
- SpawnUtilityCrate(2579, 1886, amPickHammer, 3)
- SpawnUtilityCrate(2622, 1893, amGirder, 1)
- SpawnUtilityCrate(2671, 1883, amPortalGun, 3)
- SpawnUtilityCrate(2831, 1384, amGirder, 3)
-
- SetTimer(AddGear(2725, 1387, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2760, 1351, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2805, 1287, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2831, 1376, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2684, 1409, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2637, 1428, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2278, 1280, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2311, 1160, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2339, 1162, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2362, 1184, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2407, 1117, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2437, 1143, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2472, 1309, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2495, 1331, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2536, 1340, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2569, 1360, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2619, 1379, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2596, 1246, gtMine, 0, 0, 0, 0), 5000)
-end
-
-function SkipStartAnim()
- AnimSwitchHog(natives[1])
- AnimWait(natives[1], 1)
-end
-
-function AfterStartAnim()
- HideHedge(cyborg)
- SetupPlace2()
- SetGearMessage(natives[1], 0)
- AddNewEvent(CheckGearDead, {natives[1]}, EndMission, {}, 0)
- AddNewEvent(CheckGearDead, {natives[2]}, EndMission, {}, 0)
- AddNewEvent(CheckGearDead, {natives[3]}, EndMission, {}, 0)
- AddNewEvent(CheckGearDead, {princess}, EndMission, {}, 0)
- AddNewEvent(CheckCyborgsDead, {}, DoCyborgsDead, {}, 0)
- for i = 1, cyborgsNum do
- AddNewEvent(CheckGearDead, {cyborgs[i]}, DoCyborgDead, {i}, 0)
- end
- AddNewEvent(CheckOutOfCluster, {}, DoOutOfCluster, {}, 1)
- AddNewEvent(CheckOutOfGrenade, {}, DoOutOfGrenade, {}, 1)
--- AddNewEvent(CheckNeedToHide, {}, DoNeedToHide, {}, 1)
- TurnTimeLeft = TurnTime
- ShowMission(loc("Family Reunion"), loc("Hostage Situation"), loc("Save the princess! All your hogs must survive!|Hint: Kill the cyborgs first! Use the ammo very carefully!|Hint: You might want to spare a girder for cover!"), 1, 7000)
-end
-
-function SetupPlace2()
- PlaceGirder(709, 564, 7)
- PlaceGirder(591, 677, 7)
- PlaceGirder(473, 794, 7)
- PlaceGirder(433, 933, 5)
- PlaceGirder(553, 1052, 5)
- PlaceGirder(674, 1170, 5)
- PlaceGirder(710, 1310, 7)
- PlaceGirder(648, 1427, 5)
- PlaceGirder(2110, 980, 0)
-
- SpawnAmmoCrate(814, 407, amBazooka, 4)
- clusterCrate = SpawnAmmoCrate(862, 494, amClusterBomb, 4)
- SpawnAmmoCrate(855, 486, amBee, 3)
- grenadeCrate1 = SpawnAmmoCrate(849, 459, amGrenade, 4)
- SpawnAmmoCrate(2077, 847, amWatermelon, 3)
- grenadeCrate2 = SpawnAmmoCrate(2122, 847, amGrenade, 3)
-
- SpawnUtilityCrate(747, 1577, amPickHammer, 1)
- SpawnUtilityCrate(496, 1757, amGirder, 2)
- SpawnUtilityCrate(1809, 1880, amGirder, 1)
- SpawnUtilityCrate(530, 1747, amPortalGun, 1)
-end
-
------------------------------Events------------------------------------
-function CheckPrincessFreed()
- if GetX(natives[1]) == nil or GetX(natives[2]) == nil or GetX(natives[3]) == nil or GetX(princess) == nil then
- return false
- end
- return math.abs(GetX(natives[1]) - GetX(princess)) <= 15 and math.abs(GetY(natives[1]) - GetY(princess)) <= 15 and StoppedGear(natives[1])
- and GetY(natives[2]) < 1500 and GetY(natives[3]) < 1500 and StoppedGear(natives[2]) and StoppedGear(natives[3])
-end
-
-function DoPrincessFreed()
- AnimSay(princess, loc("Thank you, my hero!"), SAY_SAY, 0)
- if progress and progress<7 then
- SaveCampaignVar("Progress", "7")
- end
- ParseCommand("teamgone " .. loc("011101001"))
- TurnTimeLeft = 0
-end
-
-function CheckCyborgsDead()
- return cyborgsLeft == 0
-end
-
-function DoCyborgsDead()
- SetGearMessage(CurrentHedgehog, 0)
- RestoreHedge(princess)
--- RemoveEventFunc(CheckNeedToHide)
- AddAnim(midAnim)
- AddFunction({func = AfterMidAnim, args = {}})
-end
-
-function DoCyborgDead(index)
- if cyborgsLeft == 0 then
- return
- end
- if index == 1 then
- SpawnAmmoCrate(1700, 407, amBazooka, 3)
- elseif index == 2 then
- SpawnAmmoCrate(1862, 494, amClusterBomb, 3)
- elseif index == 3 then
- SpawnAmmoCrate(1855, 486, amBee, 1)
- elseif index == 4 then
- SpawnAmmoCrate(1849, 459, amGrenade, 3)
- elseif index == 5 then
- SpawnAmmoCrate(2122, 847, amGrenade, 3)
- elseif index == 6 then
- SpawnAmmoCrate(2077, 847, amWatermelon, 1)
- end
-end
-
-function CheckGearsDead(gearList)
- for i = 1, # gearList do
- if gearDead[gearList[i]] ~= true then
- return false
- end
- end
- return true
-end
-
-
-function CheckGearDead(gear)
- return gearDead[gear]
-end
-
-function EndMission()
- RemoveEventFunc(CheckPrincessFreed)
- AddCaption("So the princess was never heard of again...")
- ParseCommand("teamgone " .. loc("Natives"))
- ParseCommand("teamgone " .. loc("011101001"))
- TurnTimeLeft = 0
-end
-
-function CheckOutOfCluster()
- return CheckGearDead(clusterCrate) and GetAmmoCount(natives[1], amClusterBomb) == 0
-end
-
-function CheckOutOfGrenade()
- return CheckGearDead(grenadeCrate1) and CheckGearDead(grenadeCrate2) and GetAmmoCount(natives[1], amGrenade) == 0
-end
-
-function DoOutOfCluster()
- if (GetX(natives[1]) == nil) then
- return
- end
- clusterCrate = SpawnAmmoCrate(GetX(natives[1]) - 50, GetY(natives[1]) - 50, amClusterBomb, 3)
-end
-
-function DoOutOfGrenade()
- if (GetX(natives[1]) == nil) then
- return
- end
- grenadeCrate2 = SpawnAmmoCrate(GetX(natives[1]) - 50, GetY(natives[1]) - 50, amGrenade, 3)
-end
-
-function CheckNeedToHide()
- if gearDead[princess] == true then
- return false
- end
- return TurnTimeLeft == 0
-end
-
-function DoNeedToHide()
- HideHedge(princess)
-end
------------------------------Misc--------------------------------------
-function HideHedge(hedge)
- if hedgeHidden[hedge] ~= true then
- HideHog(hedge)
- hedgeHidden[hedge] = true
- end
-end
-
-function RestoreHedge(hedge)
- if hedgeHidden[hedge] == true then
- RestoreHog(hedge)
- hedgeHidden[hedge] = false
- end
-end
-
-function GetVariables()
- progress = tonumber(GetCampaignVar("Progress"))
- m5DeployedNum = tonumber(GetCampaignVar("M5DeployedNum"))
- m2Choice = tonumber(GetCampaignVar("M2Choice"))
- m5Choice = tonumber(GetCampaignVar("M5Choice"))
-end
-
-function SetupPlace()
- SetHogHat(natives[1], nativeHats[m5DeployedNum])
- SetHogName(natives[1], nativeNames[m5DeployedNum])
- if m2Choice ~= choiceAccepted or m5Choice ~= choiceEliminate then
- DeleteGear(cyborgs[cyborgsNum])
- cyborgsNum = cyborgsNum - 1
- end
- HideHedge(cyborg)
-end
-
-function SetupAmmo()
- AddAmmo(cyborgs[1], amBazooka, 100)
- AddAmmo(cyborgs[1], amGrenade, 100)
- AddAmmo(cyborgs[1], amClusterBomb, 100)
- AddAmmo(cyborgs[1], amSniperRifle, 1)
- AddAmmo(cyborgs[1], amDynamite, 100)
- AddAmmo(cyborgs[1], amBaseballBat, 100)
- AddAmmo(cyborgs[1], amMolotov, 100)
- AddAmmo(cyborgs[1], amWatermelon, 1)
- AddAmmo(cyborgs[1], amAirStrike, 2)
- AddAmmo(cyborgs[1], amDrillStrike, 1)
-end
-
-function AddHogs()
- AddTeam(loc("Natives"), 29439, "Bone", "Island", "HillBilly", "cm_birdy")
- for i = 7, 9 do
- natives[i-6] = AddHog(nativeNames[i], 0, 100, nativeHats[i])
- gearDead[natives[i-6]] = false
- end
-
- AddTeam(loc("011101001"), 14483456, "ring", "UFO", "Robot", "cm_star")
- cyborg = AddHog(loc("Unit 334a$7%;.*"), 0, 200, "cyborg1")
- princess = AddHog(loc("Fell From Heaven"), 0, 333, "tiara")
- gearDead[cyborg] = false
- gearDead[princess] = false
-
- AddTeam(loc("Biomechanic Team"), 14483456, "ring", "UFO", "Robot", "cm_star")
- for i = 1, cyborgsNum do
- cyborgs[i] = AddHog(cyborgNames[i], cyborgsDif[i], cyborgsHealth[i], "cyborg2")
- gearDead[cyborgs[i]] = false
- end
- cyborgsLeft = cyborgsNum
-
- for i = 1, 3 do
- AnimSetGearPosition(natives[i], unpack(nativePos[i]))
- end
-
- AnimSetGearPosition(cyborg, unpack(cyborgPos))
- AnimSetGearPosition(princess, unpack(princessPos))
- AnimTurn(princess, "Left")
-
- for i = 1, cyborgsNum do
- AnimSetGearPosition(cyborgs[i], unpack(cyborgsPos[i]))
- AnimTurn(cyborgs[i], cyborgsDir[i])
- end
-end
-
-function CondNeedToTurn(hog1, hog2)
- xl, xd = GetX(hog1), GetX(hog2)
- if xl == nil or xd == nil then
- return
- end
- if xl > xd then
- AnimInsertStepNext({func = AnimTurn, args = {hog1, "Left"}})
- AnimInsertStepNext({func = AnimTurn, args = {hog2, "Right"}})
- elseif xl < xd then
- AnimInsertStepNext({func = AnimTurn, args = {hog2, "Left"}})
- AnimInsertStepNext({func = AnimTurn, args = {hog1, "Right"}})
- end
-end
-
------------------------------Main Functions----------------------------
-
-function onGameInit()
- Seed = 0
- GameFlags = gfSolidLand + gfDisableLandObjects + gfDisableGirders
- TurnTime = 60000
- CaseFreq = 0
- MinesNum = 0
- MinesTime = 3000
- Explosives = 0
- Delay = 10
- MapGen = 2
- Theme = "Hell"
- SuddenDeathTurns = 35
-
- for i = 1, #map do
- ParseCommand('draw ' .. map[i])
- end
-
- AddHogs()
- AnimInit()
-end
-
-function onGameStart()
- GetVariables()
- SetupAmmo()
- SetupPlace()
- AnimationSetup()
- AddAnim(startAnim)
- AddFunction({func = AfterStartAnim, args = {}})
-end
-
-function onGameTick()
- AnimUnWait()
- if ShowAnimation() == false then
- return
- end
- ExecuteAfterAnimations()
- CheckEvents()
-end
-
-function onGearDelete(gear)
- gearDead[gear] = true
- if GetGearType(gear) == gtHedgehog then
- if GetHogTeamName(gear) == loc("Biomechanic Team") then
- cyborgsLeft = cyborgsLeft - 1
- end
- end
-end
-
-function onAmmoStoreInit()
- SetAmmo(amSkip, 9, 0, 0, 0)
- SetAmmo(amSwitch, 9, 0, 0, 0)
- SetAmmo(amBazooka, 0, 0, 0, 8)
- SetAmmo(amClusterBomb,0, 0, 0, 8)
- SetAmmo(amBee, 0, 0, 0, 3)
- SetAmmo(amGrenade, 0, 0, 0, 8)
- SetAmmo(amWatermelon, 0, 0, 0, 2)
- SetAmmo(amSniperRifle, 0, 0, 0, 3)
- SetAmmo(amPickHammer, 0, 0, 0, 1)
- SetAmmo(amGirder, 0, 0, 0, 3)
- SetAmmo(amPortalGun, 0, 0, 0, 1)
-end
-
-function onNewTurn()
- if AnimInProgress() then
- TurnTimeLeft = -1
- return
- end
- if GetHogTeamName(CurrentHedgehog) == loc("011101001") then
- if CheckCyborgsDead() ~= true then
- for i = 1, 3 do
- if gearDead[natives[i]] ~= true then
- HideHedge(natives[i])
- end
- end
- end
- TurnTimeLeft = 0
- else
- for i = 1, 3 do
- if gearDead[natives[i]] ~= true then
- RestoreHedge(natives[i])
- end
- end
- end
-end
-
-function onPrecise()
- if GameTime > 2500 and AnimInProgress() then
- SetAnimSkip(true)
- return
- end
--- HideHedge(princess)
--- for i = 1, 5 do
--- DeleteGear(cyborgs[i])
--- end
--- AddAmmo(natives[1], amTeleport, 100)
-end
Binary file share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/first_blood.hwp has changed
--- a/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/first_blood.lua Mon Jul 01 22:28:42 2013 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,750 +0,0 @@
-HedgewarsScriptLoad("/Scripts/Locale.lua")
-HedgewarsScriptLoad("/Scripts/Animate.lua")
-
------------------------------Variables---------------------------------
-startDialogue = {}
-damageAnim = {}
-onShroomAnim = {}
-onFlowerAnim = {}
-tookParaAnim = {}
-tookPunchAnim = {}
-onMoleHeadAnim = {}
-tookRope2Anim = {}
-challengeAnim = {}
-challengeFailedAnim = {}
-challengeCompletedAnim = {}
-beforeKillAnim = {}
-closeCannim = {}
-cannKilledAnim = {}
-cannKilledEarlyAnim = {}
-princessDamagedAnim = {}
-elderDamagedAnim = {}
-pastMoleHeadAnim = {}
-
-
-targets = {}
-crates = {}
-targXdif2 = {2755, 2638, 2921, 2973, 3162, 3067, 3062, 1300}
-targYdif2 = {1197, 1537, 1646, 1857, 1804, 1173, 1167, 1183}
-targXdif1 = {2749, 2909, 2770, 2836, 1558, 1305}
-targYdif1 = {1179, 1313, 1734, 1441, 1152, 1259}
-targetPosX = {{821, 866, 789}, {614, 656, 638}, {1238, 1237, 1200}}
-targetPosY = {{1342, 1347, 1326}, {1112, 1121, 1061}, {1152, 1111, 1111}}
-crateNum = {6, 8}
-
-
-stage = 1
-cratesCollected = 0
-chalTries = 0
-targetsDestroyed = 0
-targsWave = 1
-tTime = -1
-difficulty = 0
-
-cannibalVisible = false
-cannibalKilles = false
-youngdamaged = false
-youngKilled = false
-elderDamaged = false
-princessDamaged = false
-elderKilled = false
-princessKilled = false
-rope1Taken = false
-paraTaken = false
-rope2Taken = false
-punchTaken = false
-canKilled = false
-desertTaken = false
-challengeFailed = false
-deleteCrate = false
-difficultyChoice = false
-princessFace = "Left"
-elderFace = "Left"
-
-goals = {
- [startDialogue] = {loc("First Blood"), loc("First Steps"), loc("Press [Left] or [Right] to move around, [Enter] to jump"), 1, 4000},
- [onShroomAnim] = {loc("First Blood"), loc("A leap in a leap"), loc("Go on top of the flower"), 1, 4000},
- [onFlowerAnim] = {loc("First Blood"), loc("Hightime"), loc("Collect the crate on the right.|Hint: Select the rope, [Up] or [Down] to aim, [Space] to fire, directional keys to move.|Ropes can be fired again in the air!"), 1, 7000},
- [tookParaAnim] = {loc("First Blood"), loc("Omnivore"), loc("Get on the head of the mole"), 1, 4000},
- [onMoleHeadAnim] = {loc("First Blood"), loc("The Leap of Faith"), loc("Use the parachute ([Space] while in air) to get the next crate"), 1, 4000},
- [tookRope2Anim] = {loc("First Blood"), loc("The Rising"), loc("Do the deed"), 1, 4000},
- [tookPunchAnim] = {loc("First Blood"), loc("The Slaughter"), loc("Destroy the targets!|Hint: Select the Shoryuken and hit [Space]|P.S. You can use it mid-air."), 1, 5000},
- [challengeAnim] = {loc("First Blood"), loc("The Crate Frenzy"), loc("Collect the crates within the time limit!|If you fail, you'll have to try again."), 1, 5000},
- [challengeFailedAnim] = {loc("First Blood"), loc("The Crate Frenzy"), loc("Collect the crates within the time limit!|If you fail, you'll have to try again."), 1, 5000},
- [challengeCompletedAnim] = {loc("First Blood"), loc("The Ultimate Weapon"), loc("Destroy the targets!|Hint: [Up], [Down] to aim, [Space] to shoot"), 1, 5000},
- [beforeKillAnim] = {loc("First Blood"), loc("The First Blood"), loc("Kill the cannibal!"), 1, 5000},
- [closeCannim] = {loc("First Blood"), loc("The First Blood"), loc("KILL IT!"), 1, 5000}
-}
------------------------------Animations--------------------------------
-function Skipanim(anim)
- AnimSwitchHog(youngh)
- if goals[anim] ~= nil then
- ShowMission(unpack(goals[anim]))
- end
- if anim == startDialogue then
- HogTurnLeft(princess, false)
- end
-end
-
-function SkipDamageAnim(anim)
- SwitchHog(youngh)
- SetInputMask(0xFFFFFFFF)
-end
-
-function SkipOnShroom()
- Skipanim(onShroomAnim)
- AnimSetGearPosition(elderh, 2700, 1278)
-end
-
-function AnimationSetup()
- AddSkipFunction(damageAnim, SkipDamageAnim, {damageAnim})
- table.insert(damageAnim, {func = AnimWait, args = {youngh, 500}, skipFunc = Skipanim, skipArgs = damageAnim})
- table.insert(damageAnim, {func = AnimSay, args = {elderh, loc("Watch your steps, young one!"), SAY_SAY, 2000}})
- table.insert(damageAnim, {func = AnimGearWait, args = {youngh, 500}})
-
- AddSkipFunction(princessDamagedAnim, SkipDamageAnim, {princessDamagedAnim})
- table.insert(princessDamagedAnim, {func = AnimWait, args = {princess, 500}, skipFunc = Skipanim, skipArgs = princessDamagedAnim})
- table.insert(princessDamagedAnim, {func = AnimSay, args = {princess, loc("Why do men keep hurting me?"), SAY_THINK, 3000}})
- table.insert(princessDamagedAnim, {func = AnimGearWait, args = {youngh, 500}})
-
- AddSkipFunction(elderDamagedAnim, SkipDamageAnim, {elderDamagedAnim})
- table.insert(elderDamagedAnim, {func = AnimWait, args = {elderh, 500}, skipFunc = Skipanim, skipArgs = elderDamagedAnim})
- table.insert(elderDamagedAnim, {func = AnimSay, args = {elderh, loc("Violence is not the answer to your problems!"), SAY_SAY, 3000}})
- table.insert(elderDamagedAnim, {func = AnimGearWait, args = {youngh, 500}})
-
- AddSkipFunction(startDialogue, Skipanim, {startDialogue})
- table.insert(startDialogue, {func = AnimWait, args = {youngh, 3500}, skipFunc = Skipanim, skipArgs = startDialogue})
- table.insert(startDialogue, {func = AnimCaption, args = {youngh, loc("Once upon a time, on an island with great natural resources, lived two tribes in heated conflict..."), 5000}})
- table.insert(startDialogue, {func = AnimCaption, args = {youngh, loc("One tribe was peaceful, spending their time hunting and training, enjoying the small pleasures of life..."), 5000}})
- table.insert(startDialogue, {func = AnimCaption, args = {youngh, loc("The other one were all cannibals, spending their time eating the organs of fellow hedgehogs..."), 5000}})
- table.insert(startDialogue, {func = AnimCaption, args = {youngh, loc("And so it began..."), 1000}})
- table.insert(startDialogue, {func = AnimSay, args = {elderh, loc("What are you doing at a distance so great, young one?"), SAY_SHOUT, 4000}})
- table.insert(startDialogue, {func = AnimSay, args = {elderh, loc("Come closer, so that your training may continue!"), SAY_SHOUT, 6000}})
- table.insert(startDialogue, {func = AnimSay, args = {youngh, loc("This is it! It's time to make Fell From Heaven fall for me..."), SAY_THINK, 6000}})
- table.insert(startDialogue, {func = AnimJump, args = {youngh, "long"}})
- table.insert(startDialogue, {func = AnimTurn, args = {princess, "Right"}})
- table.insert(startDialogue, {func = AnimSwitchHog, args = {youngh}})
- table.insert(startDialogue, {func = AnimShowMission, args = {youngh, loc("First Blood"), loc("First Steps"), loc("Press [Left] or [Right] to move around, [Enter] to jump"), 1, 4000}})
-
- AddSkipFunction(onShroomAnim, SkipOnShroom, {onShroomAnim})
- table.insert(onShroomAnim, {func = AnimSay, args = {elderh, loc("I can see you have been training diligently."), SAY_SAY, 4000}, skipFunc = Skipanim, skipArgs = onShroomAnim})
- table.insert(onShroomAnim, {func = AnimSay, args = {elderh, loc("The wind whispers that you are ready to become familiar with tools, now..."), SAY_SAY, 4000}})
- table.insert(onShroomAnim, {func = AnimSay, args = {elderh, loc("Open that crate and we will continue!"), SAY_SAY, 5000}})
- table.insert(onShroomAnim, {func = AnimMove, args = {elderh, "Right", 2700, 0}})
- table.insert(onShroomAnim, {func = AnimTurn, args = {elderh, "Left"}})
- table.insert(onShroomAnim, {func = AnimSay, args = {princess, loc("He moves like an eagle in the sky."), SAY_THINK, 4000}})
- table.insert(onShroomAnim, {func = AnimSwitchHog, args = {youngh}})
- table.insert(onShroomAnim, {func = AnimShowMission, args = {youngh, loc("First Blood"), loc("A leap in a leap"), loc("Go on top of the flower"), 1, 4000}})
-
- AddSkipFunction(onFlowerAnim, Skipanim, {onFlowerAnim})
- table.insert(onFlowerAnim, {func = AnimSay, args = {elderh, loc("See that crate farther on the right?"), SAY_SAY, 4000}})
- table.insert(onFlowerAnim, {func = AnimSay, args = {elderh, loc("Swing, Leaks A Lot, on the wings of the wind!"), SAY_SAY, 6000}})
- table.insert(onFlowerAnim, {func = AnimSay, args = {princess, loc("His arms are so strong!"), SAY_THINK, 4000}})
- table.insert(onFlowerAnim, {func = AnimSwitchHog, args = {youngh}})
- table.insert(onFlowerAnim, {func = AnimShowMission, args = {youngh, loc("First Blood"), loc("Hightime"), loc("Collect the crate on the right.|Hint: Select the rope, [Up] or [Down] to aim, [Space] to fire, directional keys to move.|Ropes can be fired again in the air!"), 1, 7000}})
-
- AddSkipFunction(tookParaAnim, Skipanim, {tookParaAnim})
- table.insert(tookParaAnim, {func = AnimGearWait, args = {youngh, 1000}, skipFunc = Skipanim, skipArgs = tookParaAnim})
- table.insert(tookParaAnim, {func = AnimSay, args = {elderh, loc("Use the rope to get on the head of the mole, young one!"), SAY_SHOUT, 4000}})
- table.insert(tookParaAnim, {func = AnimSay, args = {elderh, loc("Worry not, for it is a peaceful animal! There is no reason to be afraid..."), SAY_SHOUT, 5000}})
- table.insert(tookParaAnim, {func = AnimSay, args = {elderh, loc("We all know what happens when you get frightened..."), SAY_SAY, 4000}})
- table.insert(tookParaAnim, {func = AnimSay, args = {youngh, loc("So humiliating..."), SAY_SAY, 4000}})
- table.insert(tookParaAnim, {func = AnimShowMission, args = {youngh, loc("First Blood"), loc("Omnivore"), loc("Get on the head of the mole"), 1, 4000}})
- table.insert(tookParaAnim, {func = AnimSwitchHog, args = {youngh}})
-
- AddSkipFunction(onMoleHeadAnim, Skipanim, {onMoleHeadAnim})
- table.insert(onMoleHeadAnim, {func = AnimSay, args = {elderh, loc("Perfect! Now try to get the next crate without hurting yourself!"), SAY_SAY, 4000}, skipFunc = Skipanim, skipArgs = onMoleHeadAnim})
- table.insert(onMoleHeadAnim, {func = AnimSay, args = {elderh, loc("The giant umbrella from the last crate should help break the fall."), SAY_SAY, 4000}})
- table.insert(onMoleHeadAnim, {func = AnimSay, args = {princess, loc("He's so brave..."), SAY_THINK, 4000}})
- table.insert(onMoleHeadAnim, {func = AnimShowMission, args = {youngh, loc("First Blood"), loc("The Leap of Faith"), loc("Use the parachute ([Space] while in air) to get the next crate"), 1, 4000}})
- table.insert(onMoleHeadAnim, {func = AnimSwitchHog, args = {youngh}})
-
- AddSkipFunction(pastMoleHeadAnim, Skipanim, {pastMoleHeadAnim})
- table.insert(pastMoleHeadAnim, {func = AnimSay, args = {elderh, loc("I see you have already taken the leap of faith."), SAY_SAY, 4000}, skipFunc = Skipanim, skipArgs = pastMoleHeadAnim})
- table.insert(pastMoleHeadAnim, {func = AnimSay, args = {elderh, loc("Get that crate!"), SAY_SAY, 4000}})
- table.insert(pastMoleHeadAnim, {func = AnimSwitchHog, args = {youngh}})
-
- AddSkipFunction(tookRope2Anim, Skipanim, {tookRope2Anim})
- table.insert(tookRope2Anim, {func = AnimSay, args = {elderh, loc("Impressive...you are still dry as the corpse of a hawk after a week in the desert..."), SAY_SAY, 5000}, skipFunc = Skipanim, skipArgs = tookRope2Anim})
- table.insert(tookRope2Anim, {func = AnimSay, args = {elderh, loc("You probably know what to do next..."), SAY_SAY, 4000}})
- table.insert(tookRope2Anim, {func = AnimShowMission, args = {youngh, loc("First Blood"), loc("The Rising"), loc("Do the deed"), 1, 4000}})
- table.insert(tookRope2Anim, {func = AnimSwitchHog, args = {youngh}})
-
- AddSkipFunction(tookPunchAnim, Skipanim, {tookPunchAnim})
- table.insert(tookPunchAnim, {func = AnimSay, args = {elderh, loc("It is time to practice your fighting skills."), SAY_SAY, 4000}})
- table.insert(tookPunchAnim, {func = AnimSay, args = {elderh, loc("Imagine those targets are the wolves that killed your parents! Take your anger out on them!"), SAY_SAY, 5000}})
- table.insert(tookPunchAnim, {func = AnimShowMission, args = {youngh, loc("First Blood"), loc("The Slaughter"), loc("Destroy the targets!|Hint: Select the Shoryuken and hit [Space]|P.S. You can use it mid-air."), 1, 5000}})
- table.insert(tookPunchAnim, {func = AnimSwitchHog, args = {youngh}})
-
- AddSkipFunction(challengeAnim, Skipanim, {challengeAnim})
- table.insert(challengeAnim, {func = AnimSay, args = {elderh, loc("I hope you are prepared for a small challenge, young one."), SAY_SAY, 4000}, skipFunc = Skipanim, skipArgs = challengeAnim})
- table.insert(challengeAnim, {func = AnimSay, args = {elderh, loc("Your movement skills will be evaluated now."), SAY_SAY, 4000}})
- table.insert(challengeAnim, {func = AnimSay, args = {elderh, loc("Collect all the crates, but remember, our time in this life is limited!"), SAY_SAY, 4000}})
- table.insert(challengeAnim, {func = AnimSay, args = {elderh, loc("How difficult would you like it to be?")}})
- table.insert(challengeAnim, {func = AnimSwitchHog, args = {youngh}})
- table.insert(challengeAnim, {func = AnimWait, args = {youngh, 500}})
-
- AddSkipFunction(challengeFailedAnim, Skipanim, {challengeFailedAnim})
- table.insert(challengeFailedAnim, {func = AnimSay, args = {elderh, loc("Hmmm...perhaps a little more time will help."), SAY_SAY, 4000}, skipFunc = Skipanim, skipArgs = challengeFailedAnim})
- table.insert(challengeFailedAnim, {func = AnimShowMission, args = {youngh, loc("First Blood"), loc("The Crate Frenzy"), loc("Collect the crates within the time limit!|If you fail, you'll have to try again."), 1, 5000}})
- table.insert(challengeFailedAnim, {func = AnimSwitchHog, args = {youngh}})
-
- AddSkipFunction(challengeCompletedAnim, Skipanim, {challengeCompletedAnim})
- table.insert(challengeCompletedAnim, {func = AnimSay, args = {elderh, loc("The spirits of the ancerstors are surely pleased, Leaks A Lot."), SAY_SAY, 4000}, skipFunc = Skipanim, skipArgs = challengeCompletedAnim})
- table.insert(challengeCompletedAnim, {func = AnimSay, args = {elderh, loc("You have proven yourself worthy to see our most ancient secret!"), SAY_SAY, 4000}})
- table.insert(challengeCompletedAnim, {func = AnimSay, args = {elderh, loc("The weapon in that last crate was bestowed upon us by the ancients!"), SAY_SAY, 4000}})
- table.insert(challengeCompletedAnim, {func = AnimSay, args = {elderh, loc("Use it with precaution!"), SAY_SAY, 4000}})
- table.insert(challengeCompletedAnim, {func = AnimShowMission, args = {youngh, loc("First Blood"), loc("The Ultimate Weapon"), loc("Destroy the targets!|Hint: [Up], [Down] to aim, [Space] to shoot"), 1, 5000}})
- table.insert(challengeCompletedAnim, {func = AnimSwitchHog, args = {youngh}})
-
- AddSkipFunction(beforeKillAnim, Skipanim, {beforeKillAnim})
- table.insert(beforeKillAnim, {func = AnimSay, args = {elderh, loc("What do my faulty eyes observe? A spy!"), SAY_SHOUT, 4000}, skipFunc = Skipanim, skipArgs = beforeKillAnim})
- table.insert(beforeKillAnim, {func = AnimFollowGear, args = {cannibal}})
- table.insert(beforeKillAnim, {func = AnimWait, args = {cannibal, 1000}})
- table.insert(beforeKillAnim, {func = AnimSay, args = {elderh, loc("Destroy him, Leaks A Lot! He is responsible for the deaths of many of us!"), SAY_SHOUT, 4000}})
- table.insert(beforeKillAnim, {func = AnimSay, args = {cannibal, loc("Oh, my!"), SAY_THINK, 4000}})
- table.insert(beforeKillAnim, {func = AnimShowMission, args = {youngh, loc("First Blood"), loc("The First Blood"), loc("Kill the cannibal!"), 1, 5000}})
- table.insert(beforeKillAnim, {func = AnimSwitchHog, args = {youngh}})
-
- AddSkipFunction(closeCannim, Skipanim, {closeCannim})
- table.insert(closeCannim, {func = AnimSay, args = {elderh, loc("I see you would like his punishment to be more...personal..."), SAY_SAY, 4000}, skipFunc = Skipanim, skipArgs = closeCannim})
- table.insert(closeCannim, {func = AnimSay, args = {cannibal, loc("I'm certain that this is a misunderstanding, fellow hedgehogs!"), SAY_SAY, 4000}})
- table.insert(closeCannim, {func = AnimSay, args = {cannibal, loc("If only I were given a chance to explain my being here..."), SAY_SAY, 4000}})
- table.insert(closeCannim, {func = AnimSay, args = {elderh, loc("Do not let his words fool you, young one! He will stab you in the back as soon as you turn away!"), SAY_SAY, 6000}})
- table.insert(closeCannim, {func = AnimSay, args = {elderh, loc("Here...pick your weapon!"), SAY_SAY, 5000}})
- table.insert(closeCannim, {func = AnimShowMission, args = {youngh, loc("First Blood"), loc("The First Blood"), loc("KILL IT!"), 1, 5000}})
- table.insert(closeCannim, {func = AnimSwitchHog, args = {youngh}})
-
- table.insert(cannKilledAnim, {func = AnimSay, args = {elderh, loc("Yes, yeees! You are now ready to enter the real world!"), SAY_SHOUT, 6000}})
-
- table.insert(cannKilledEarlyAnim, {func = AnimSay, args = {elderh, loc("What?! A cannibal? Here? There is no time to waste! Come, you are prepared."), SAY_SHOUT, 4000}})
-end
------------------------------Events------------------------------------
-function CheckNeedToTurn(gear)
- if youngKilled then
- return false
- end
- if gear == princess then
- if princessKilled ~= true then
- if (GetX(princess) > GetX(youngh) and princessFace == "Right")
- or (GetX(princess) < GetX(youngh) and princessFace == "Left") then
- --if (GetX(princess) > GetX(youngh))
- -- or (GetX(princess) < GetX(youngh)) then
- return true
- end
- end
- else
- if elderKilled ~= true then
- if (GetX(elderh) > GetX(youngh) and elderFace == "Right")
- or (GetX(elderh) < GetX(youngh) and elderFace == "Left") then
- return true
- end
- end
- end
- return false
-end
-
-function DoNeedToTurn(gear)
- if gear == princess then
- if GetX(princess) > GetX(youngh) then
- HogTurnLeft(princess, true)
- princessFace = "Left"
- elseif GetX(princess) < GetX(youngh) then
- HogTurnLeft(princess, false)
- princessFace = "Right"
- end
- else
- if GetX(elderh) > GetX(youngh) then
- HogTurnLeft(elderh, true)
- elderFace = "Left"
- elseif GetX(elderh) < GetX(youngh) then
- HogTurnLeft(elderh, false)
- elderFace = "Right"
- end
- end
-end
-
-function CheckDamage()
- return youngdamaged and StoppedGear(youngh)
-end
-
-function DoOnDamage()
- AddAnim(damageAnim)
- youngdamaged = false
- AddFunction({func = ResetTurnTime, args = {}})
-end
-
-function CheckDeath()
- return youngKilled
-end
-
-function DoDeath()
- RemoveEventFunc(CheckKilledOthers)
- RemoveEventFunc(CheckDamage)
- RemoveEventFunc(CheckDamagedOthers)
- FinishThem()
- ShowMission(loc("First Blood"), loc("The wasted youth"), loc("Leaks A Lot gave his life for his tribe! He should have survived!"), 2, 4000)
-end
-
-function CheckDamagedOthers()
- return (princessDamaged and StoppedGear(princess)) or (elderDamaged and StoppedGear(elderh))
-end
-
-function CheckKilledOthers()
- return princessKilled or elderKilled
-end
-
-function DoOnDamagedOthers()
- if princessDamaged then
- AddAnim(princessDamagedAnim)
- end
- if elderDamaged then
- AddAnim(elderDamagedAnim)
- end
- elderDamaged = false
- princessDamaged = false
- AddFunction({func = ResetTurnTime, args = {}})
-end
-
-function DoKilledOthers()
- AddCaption(loc("After Leaks A Lot betrayed his tribe, he joined the cannibals..."))
- FinishThem()
-end
-
-function CheckMovedUntilJump()
- return GetX(youngh) >= 2343
-end
-
-function DoMovedUntilJump()
- ShowMission(loc("First Blood"), loc("Step By Step"), loc("Hint: Double Jump - Press [Backspace] twice"), -amSkip, 0)
- AddEvent(CheckOnShroom, {}, DoOnShroom, {}, 0)
-end
-
-function CheckOnShroom()
- return GetX(youngh) >= 2461 and StoppedGear(youngh)
-end
-
-function DoOnShroom()
- ropeCrate1 = SpawnUtilityCrate(2751, 1194, amRope)
- SetGearMessage(CurrentHedgehog, 0)
- AddAnim(onShroomAnim)
- AddEvent(CheckOnFlower, {}, DoOnFlower, {}, 0)
-end
-
-function CheckOnFlower()
- return rope1Taken and StoppedGear(youngh)
-end
-
-function DoOnFlower()
- AddAmmo(youngh, amRope, 100)
- paraCrate = SpawnUtilityCrate(3245, 1758, amParachute)
- SetGearMessage(CurrentHedgehog, 0)
- AddAnim(onFlowerAnim)
- AddEvent(CheckTookParaCrate, {}, DoTookParaCrate, {}, 0)
-end
-
-function CheckTookParaCrate()
- return paraTaken and StoppedGear(youngh)
-end
-
-function DoTookParaCrate()
- AddAmmo(youngh, amParachute, 100)
- SetGearMessage(CurrentHedgehog, 0)
- AddAnim(tookParaAnim)
- AddEvent(CheckOnMoleHead, {}, DoOnMoleHead, {}, 0)
- AddEvent(CheckPastMoleHead, {}, DoPastMoleHead, {}, 0)
-end
-
-function CheckOnMoleHead()
- x = GetX(youngh)
- return x >= 3005 and x <= 3126 and StoppedGear(youngh)
-end
-
-function CheckPastMoleHead()
- x = GetX(youngh)
- y = GetY(youngh)
- return x < 3005 and y > 1500 and StoppedGear(youngh)
-end
-
-function DoPastMoleHead()
- RemoveEventFunc(CheckOnMoleHead)
- ropeCrate2 = SpawnUtilityCrate(2782, 1720, amRope)
- AddAmmo(youngh, amRope, 0)
- SetGearMessage(CurrentHedgehog, 0)
- AddAnim(pastMoleHeadAnim)
- AddEvent(CheckTookRope2, {}, DoTookRope2, {}, 0)
-end
-
-function DoOnMoleHead()
- RemoveEventFunc(CheckPastMoleHead)
- ropeCrate2 = SpawnUtilityCrate(2782, 1720, amRope)
- AddAmmo(youngh, amRope, 0)
- SetGearMessage(CurrentHedgehog, 0)
- AddAnim(onMoleHeadAnim)
- AddEvent(CheckTookRope2, {}, DoTookRope2, {}, 0)
-end
-
-function CheckTookRope2()
- return rope2Taken and StoppedGear(youngh)
-end
-
-function DoTookRope2()
- AddAmmo(youngh, amRope, 100)
- SetGearMessage(CurrentHedgehog, 0)
- AddAnim(tookRope2Anim)
- punchCrate = SpawnAmmoCrate(2460, 1321, amFirePunch)
- AddEvent(CheckTookPunch, {}, DoTookPunch, {})
-end
-
-function CheckTookPunch()
- return punchTaken and StoppedGear(youngh)
-end
-
-function DoTookPunch()
- AddAmmo(youngh, amFirePunch, 100)
- AddAmmo(youngh, amRope, 0)
- SetGearMessage(CurrentHedgehog, 0)
- AddAnim(tookPunchAnim)
- targets[1] = AddGear(1594, 1185, gtTarget, 0, 0, 0, 0)
- targets[2] = AddGear(2188, 1314, gtTarget, 0, 0, 0, 0)
- targets[3] = AddGear(1961, 1318, gtTarget, 0, 0, 0, 0)
- targets[4] = AddGear(1961, 1200, gtTarget, 0, 0, 0, 0)
- targets[5] = AddGear(1800, 900, gtTarget, 0, 0, 0, 0)
- AddEvent(CheckTargDestroyed, {}, DoTargDestroyed, {}, 0)
-end
-
-function CheckTargDestroyed()
- return targetsDestroyed == 5 and StoppedGear(youngh)
-end
-
-function DoTargDestroyed()
- SetGearMessage(CurrentHedgehog, 0)
- AddAnim(challengeAnim)
- targetsDestroyed = 0
- AddFunction({func = SetChoice, args = {}})
- ropeCrate3 = SpawnAmmoCrate(2000, 1200, amRope)
- AddEvent(CheckTookRope3, {}, AddAmmo, {youngh, amRope, 100}, 0)
- AddEvent(CheckCratesColled, {}, DoCratesColled, {}, 0)
- AddEvent(CheckChallengeWon, {}, DoChallengeWon, {}, 0)
- AddEvent(CheckTimesUp, {}, DoTimesUp, {}, 1)
-end
-
-function CheckChoice()
- return difficulty ~= 0
-end
-
-function DoChoice()
- difficultyChoice = false
- SetInputMask(0xFFFFFFFF)
- StartChallenge(120000 + chalTries * 20000)
-end
-
-function CheckCratesColled()
- return cratesCollected == crateNum[difficulty]
-end
-
-function DoCratesColled()
- RemoveEventFunc(CheckTimesUp)
- TurnTimeLeft = -1
- AddCaption(loc("As the challenge was completed, Leaks A Lot set foot on the ground..."))
-end
-
-function CheckChallengeWon()
- return cratesCollected == crateNum[difficulty] and StoppedGear(youngh)
-end
-
-function DoChallengeWon()
- desertCrate = SpawnAmmoCrate(1240, 1212, amDEagle)
- SetGearMessage(CurrentHedgehog, 0)
- AddAnim(challengeCompletedAnim)
- AddEvent(CheckDesertColled, {}, DoDesertColled, {}, 0)
-end
-
-function CheckTookRope3()
- return rope3Taken
-end
-
-function CheckTimesUp()
- return TurnTimeLeft == 100
-end
-
-function DoTimesUp()
- challengeFailed = true
- deleteCrate = true
- DeleteGear(crates[1])
- TurnTimeLeft = -1
- AddCaption(loc("And so happenned that Leaks A Lot failed to complete the challenge! He landed, pressured by shame..."))
- AddEvent(CheckChallengeFailed, {}, DoChallengeFailed, {}, 0)
-end
-
-function CheckChallengeFailed()
- return challengeFailed and StoppedGear(youngh)
-end
-
-function DoChallengeFailed()
- challengeFailed = false
- SetGearMessage(CurrentHedgehog, 0)
- AddAnim(challengeFailedAnim)
- chalTries = chalTries + 1
- difficulty = 0
- AddFunction({func = SetChoice, args = {}})
-end
-
-function CheckDesertColled()
- return desertTaken and StoppedGear(youngh)
-end
-
-function DoDesertColled()
- AddAmmo(youngh, amDEagle, 100)
- PutTargets(1)
- AddEvent(CheckTargetsKilled, {}, DoTargetsKilled, {}, 1)
- AddEvent(CheckCannibalKilled, {}, DoCannibalKilledEarly, {}, 0)
- ShowMission(loc("First Blood"), loc("The Bull's Eye"), loc("[Up], [Down] to aim, [Space] to shoot!"), 1, 5000)
-end
-
-function CheckTargetsKilled()
- return targetsDestroyed == 3 and StoppedGear(youngh)
-end
-
-function DoTargetsKilled()
- targetsDestroyed = 0
- targsWave = targsWave + 1
- if targsWave > 3 then
- RemoveEventFunc(CheckTargetsKilled)
- SetState(cannibal, gstVisible)
- cannibalVisible = true
- SetGearMessage(CurrentHedgehog, 0)
- AddAnim(beforeKillAnim)
- AddEvent(CheckCloseToCannibal, {}, DoCloseToCannibal, {}, 0)
- AddEvent(CheckCannibalKilled, {}, DoCannibalKilled, {}, 0)
- else
- PutTargets(targsWave)
- end
-end
-
-function CheckCloseToCannibal()
- if CheckCannibalKilled() then
- return false
- end
- return math.abs(GetX(cannibal) - GetX(youngh)) <= 400 and StoppedGear(youngh)
-end
-
-function DoCloseToCannibal()
- SetGearMessage(CurrentHedgehog, 0)
- AddAnim(closeCannim)
- AddFunction({func = SpawnAmmoCrate, args = {targetPosX[1][1], targetPosY[1][1], amWhip}})
- AddFunction({func = SpawnAmmoCrate, args = {targetPosX[1][2], targetPosY[1][2], amBaseballBat}})
- AddFunction({func = SpawnAmmoCrate, args = {targetPosX[1][3], targetPosY[1][3], amHammer}})
-end
-
-function CheckCannibalKilled()
- return cannibalKilled and StoppedGear(youngh)
-end
-
-function DoCannibalKilled()
- AddAnim(cannKilledAnim)
- if not progress then
- SaveCampaignVar("Progress", "1")
- end
-end
-
-function DoCannibalKilledEarly()
- AddAnim(cannKilledEarlyAnim)
- DoCannibalKilled()
-end
-
------------------------------Misc--------------------------------------
-function StartChallenge(time)
- cratesCollected = 0
- PutCrate(1)
- TurnTimeLeft = time
- ShowMission(loc("First Blood"), loc("The Crate Frenzy"), loc("Collect the crates within the time limit!|If you fail, you'll have to try again."), 1, 5000)
-end
-
-function SetChoice()
- SetInputMask(band(0xFFFFFFFF, bnot(gmAnimate+gmAttack+gmDown+gmHJump+gmLJump+gmSlot+gmSwitch+gmTimer+gmUp+gmWeapon)))
- difficultyChoice = true
- ShowMission(loc("First Blood"), loc("The Torment"), loc("Select difficulty: [Left] - easier or [Right] - harder"), 0, 4000)
- AddEvent(CheckChoice, {}, DoChoice, {}, 0)
-end
-
-function SetTime(time)
- TurnTimeLeft = time
-end
-
-function ResetTurnTime()
- TurnTimeLeft = tTime
- tTime = -1
-end
-
-function PutCrate(i)
- if i > crateNum[difficulty] then
- return
- end
- if difficulty == 1 then
- crates[1] = SpawnAmmoCrate(targXdif1[i], targYdif1[i], amRope)
- else
- crates[1] = SpawnAmmoCrate(targXdif2[i], targYdif2[i], amRope)
- end
-end
-
-function PutTargets(i)
- targets[1] = AddGear(targetPosX[i][1], targetPosY[i][1], gtTarget, 0, 0, 0, 0)
- targets[2] = AddGear(targetPosX[i][2], targetPosY[i][2], gtTarget, 0, 0, 0, 0)
- targets[3] = AddGear(targetPosX[i][3], targetPosY[i][3], gtTarget, 0, 0, 0, 0)
-end
-
-function FinishThem()
- SetHealth(elderh, 0)
- SetHealth(youngh, 0)
- SetHealth(princess, 0)
-end
------------------------------Main Functions----------------------------
-
-function onGameInit()
- Seed = 69
- GameFlags = gfInfAttack + gfSolidLand + gfDisableWind
- TurnTime = 100000
- CaseFreq = 0
- MinesNum = 0
- MinesTime = 3000
- Explosives = 0
- Delay = 10
- Map = "A_Classic_Fairytale_first_blood"
- Theme = "Nature"
-
-
- AddTeam(loc("Natives"), 29439, "Bone", "Island", "HillBilly", "cm_birdy")
- youngh = AddHog(loc("Leaks A Lot"), 0, 100, "Rambo")
- elderh = AddHog(loc("Righteous Beard"), 0, 99, "IndianChief")
- princess = AddHog(loc("Fell From Heaven"), 0, 300, "tiara")
- AnimSetGearPosition(princess, 1911, 1361)
- HogTurnLeft(princess, true)
- AnimSetGearPosition(elderh, 2667, 1208)
- HogTurnLeft(elderh, true)
- AnimSetGearPosition(youngh, 1862, 1362)
- HogTurnLeft(youngh, false)
-
- AddTeam(loc("Cannibals"), 14483456, "Skull", "Island", "Pirate","cm_vampire")
- cannibal = AddHog(loc("Brainiac"), 0, 5, "Zombi")
- AnimSetGearPosition(cannibal, 525, 1256)
- HogTurnLeft(cannibal, false)
-
- AnimInit()
- AnimationSetup()
-end
-
-function onGameStart()
- progress = tonumber(GetCampaignVar("Progress"))
- TurnTimeLeft = -1
- FollowGear(youngh)
- ShowMission(loc("A Classic Fairytale"), loc("First Blood"), loc("Finish your training|Hint: Animations can be skipped with the [Precise] key."), -amSkip, 0)
- SetState(cannibal, gstInvisible)
-
- AddAnim(startDialogue)
- princessFace = "Right"
- AddEvent(CheckNeedToTurn, {princess}, DoNeedToTurn, {princess}, 1)
- AddEvent(CheckNeedToTurn, {elderh}, DoNeedToTurn, {elderh}, 1)
- AddEvent(CheckDamage, {}, DoOnDamage, {}, 1)
- AddEvent(CheckDeath, {}, DoDeath, {}, 0)
- AddEvent(CheckDamagedOthers, {}, DoOnDamagedOthers, {}, 1)
- AddEvent(CheckKilledOthers, {}, DoKilledOthers, {}, 0)
- AddEvent(CheckMovedUntilJump, {}, DoMovedUntilJump, {}, 0)
-end
-
-function onGameTick()
- AnimUnWait()
- if ShowAnimation() == false then
- return
- end
- ExecuteAfterAnimations()
- CheckEvents()
-end
-
-function onGearDelete(gear)
- if gear == ropeCrate1 then
- rope1Taken = true
- elseif gear == paraCrate then
- paraTaken = true
- elseif gear == ropeCrate2 then
- rope2Taken = true
- elseif gear == ropeCrate3 then
- rope3Taken = true
- elseif gear == crates[1] and deleteCrate == true then
- deleteCrate = false
- elseif gear == crates[1] and challengeFailed == false then
- crates[1] = nil
- cratesCollected = cratesCollected + 1
- PutCrate(cratesCollected + 1)
- elseif gear == punchCrate then
- punchTaken = true
- elseif gear == desertCrate then
- desertTaken = true
- elseif GetGearType(gear) == gtTarget then
- i = 1
- while targets[i] ~= gear do
- i = i + 1
- end
- targets[i] = nil
- targetsDestroyed = targetsDestroyed + 1
- elseif gear == cannibal then
- cannibalKilled = true
- elseif gear == princess then
- princessKilled = true
- elseif gear == elderh then
- elderKilled = true
- elseif gear == youngh then
- youngKilled = true
- end
-end
-
-function onAmmoStoreInit()
- SetAmmo(amWhip, 0, 0, 0, 8)
- SetAmmo(amBaseballBat, 0, 0, 0, 8)
- SetAmmo(amHammer, 0, 0, 0, 8)
-end
-
-function onNewTurn()
- if CurrentHedgehog == cannibal and cannibalVisible == false then
- SetState(cannibal, gstInvisible)
- end
- SwitchHog(youngh)
- FollowGear(youngh)
- TurnTimeLeft = -1
-end
-
-function onGearDamage(gear, damage)
- if gear == youngh then
- youngdamaged = true
- tTime = TurnTimeLeft
- elseif gear == princess then
- princessDamaged = true
- tTime = TurnTimeLeft
- elseif gear == elderh then
- elderDamaged = true
- tTime = TurnTimeLeft
- elseif gear == cannibal then
- cannibalVisible = true
- cannibalDamaged = true
- SetState(cannibal, 0)
- end
-end
-
-function onPrecise()
- if GameTime > 2000 then
- SetAnimSkip(true)
- end
-end
-
-function onLeft()
- if difficultyChoice == true then
- difficulty = 1
- end
-end
-
-function onRight()
- if difficultyChoice == true then
- difficulty = 2
- end
-end
-
Binary file share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/journey.hwp has changed
--- a/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/journey.lua Mon Jul 01 22:28:42 2013 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1077 +0,0 @@
-HedgewarsScriptLoad("/Scripts/Locale.lua")
-HedgewarsScriptLoad("/Scripts/Animate.lua")
-
---///////////////////////////////CONSTANTS///////////////////////////
-
-choiceAccepted = 1
-choiceRefused = 2
-choiceAttacked = 3
-
-endStage = 1
-
-cannibalNum = 8
-cannibalNames = {loc("John"), loc("Flesh for Brainz"), loc("Eye Chewer"), loc("Torn Muscle"),
- loc("Nom-Nom"), loc("Vedgies"), loc("Brain Blower"), loc("Gorkij")}
-cannibalPos = {{2471, 1174}, {939, 1019}, {1953, 902}, {3055, 1041},
- {1121, 729}, {1150, 718}, {1149, 680}, {1161, 773}}
-
-startLeaksPosDuo = {3572, 1426}
-startEventXDuo = 3300
-startDensePosDuo = {3454, 1471}
-startCyborgPosDuo = {3202, 1307}
-midDensePosDuo = {1464, 1410}
-midCyborgPosDuo = {1264, 1390}
-
---///////////////////////////////VARIABLES///////////////////////////
-
-m2Choice = 0
-m2DenseDead = 0
-m2RamonDead = 0
-m2SpikyDead = 0
-
-TurnsLeft = 0
-stage = 0
-
---cyborgHidden = false
---princessHidden = false
-blowTaken = false
-fireTaken = false
-gravityTaken = false
-sniperTaken = false
-girderTaken = false
-girder1Taken = false
-girder2Taken = false
-leaksDead = false
-denseDead = false
-princessDead = false
-cyborgDead = false
-cannibalDead = {}
-hedgeHidden = {}
-
-startAnim = {}
-startAnimAD = {}
-startAnimAL = {}
-startAnimRL = {}
-
-pastFlowerAnimAL = {}
-pastFlowerAnimRL = {}
-pastFlowerAnim = {}
-
-outPitAnimAL = {}
-outPitAnimRL = {}
-outPitAnim = {}
-
-midAnim = {}
-midAnimAD = {}
-
-failAnim = {}
-failAnimAD = {}
-
-endAnim = {}
-endAnimAD = {}
-endAnimAL = {}
-endAnimRL = {}
-
-endFailAnim = {}
-endFailAnimAD = {}
-
-winAnim = {}
-winAnimAD = {}
-
---/////////////////////////Animation Functions///////////////////////
-function AfterMidFailAnim()
- ParseCommand("teamgone " .. loc("Natives"))
- TurnTimeLeft = 0
-end
-
-function AfterMidAnimAlone()
- SetupCourse()
- for i = 5, 8 do
- RestoreHedge(cannibals[i])
- AnimSetGearPosition(cannibals[i], unpack(cannibalPos[i]))
- end
-
- AddAmmo(cannibals[5], amDEagle, 0)
-
- AddEvent(CheckGirderTaken, {}, DoGirderTaken, {}, 0)
- AddEvent(CheckOnFirstGirder, {}, DoOnFirstGirder, {}, 0)
- AddEvent(CheckTookSniper, {}, DoTookSniper, {}, 0)
- AddEvent(CheckFailedCourse, {}, DoFailedCourse, {}, 0)
- SetGearMessage(leaks, 0)
- TurnsLeft = 12
- TurnTimeLeft = TurnTime
- ShowMission(loc("The Journey Back"), loc("Collateral Damage"), loc("Save the princess by collecting the crate in under 12 turns!"), 0, 6000)
- -----------------------///////////////------------
- --AnimSetGearPosition(leaks, 417, 1800)
-end
-
-function SkipEndAnimAlone()
- RestoreHedge(cyborg)
- RestoreHedge(princess)
- AnimSetGearPosition(cyborg, 437, 1700)
- AnimSetGearPosition(princess, 519, 1722)
-end
-
-function SkipEndAnimDuo()
- RestoreHedge(cyborg)
- RestoreHedge(princess)
- if princessHidden then
- RestoreHog(princess)
- princessHidden = false
- end
- AnimSetGearPosition(cyborg, 437, 1700)
- AnimSetGearPosition(princess, 519, 1722)
- AnimSetGearPosition(leaks, 763, 1760)
- AnimSetGearPosition(dense, 835, 1519)
- HogTurnLeft(leaks, true)
- HogTurnLeft(dense, true)
-end
-
-function AfterEndAnimAlone()
- stage = endStage
- SwitchHog(leaks)
- SetGearMessage(leaks, 0)
- TurnTimeLeft = -1
- ShowMission(loc("The Journey Back"), loc("Collateral Damage II"), loc("Save Fell From Heaven!"), 1, 4000)
- AddEvent(CheckLost, {}, DoLost, {}, 0)
- AddEvent(CheckWon, {}, DoWon, {}, 0)
- RemoveEventFunc(CheckFailedCourse)
-end
-
-function AfterEndAnimDuo()
- stage = endStage
- SwitchHog(leaks)
- SetGearMessage(leaks, 0)
- SetGearMessage(dense, 0)
- TurnTimeLeft = -1
- ShowMission(loc("The Journey Back"), loc("Collateral Damage II"), loc("Save Fell From Heaven!"), 1, 4000)
- AddEvent(CheckLost, {}, DoLost, {}, 0)
- AddEvent(CheckWon, {}, DoWon, {}, 0)
-end
-
-function SkipMidAnimAlone()
- AnimSetGearPosition(leaks, 2656, 1842)
- AnimSwitchHog(leaks)
- SetInputMask(0xFFFFFFFF)
- AnimWait(dense, 1)
- AddFunction({func = HideHedge, args = {princess}})
- AddFunction({func = HideHedge, args = {cyborg}})
-end
-
-function AfterStartAnim()
- SetGearMessage(leaks, 0)
- TurnTimeLeft = TurnTime
- local goal = loc("Get the crate on the other side of the island!|")
- local hint = loc("Hint: you might want to stay out of sight and take all the crates...|")
- local stuck = loc("If you get stuck, use your Desert Eagle or restart the mission!|")
- local conds = loc("Leaks A Lot must survive!")
- if m2DenseDead == 0 then
- conds = loc("Your hogs must survive!")
- end
- ShowMission(loc("The Journey Back"), loc("Adventurous"), goal .. hint .. stuck .. conds, 0, 7000)
-end
-
-function SkipStartAnim()
- AnimSwitchHog(leaks)
-end
-
-function PlaceCratesDuo()
- SpawnAmmoCrate(3090, 827, amBaseballBat)
- girderCrate1 = SpawnUtilityCrate(2466, 1814, amGirder)
- girderCrate2 = SpawnUtilityCrate(2630, 1278, amGirder)
- SpawnUtilityCrate(2422, 1810, amParachute)
- SpawnUtilityCrate(3157, 1009, amLowGravity)
- sniperCrate = SpawnAmmoCrate(784, 1715, amSniperRifle)
-end
-
-function PlaceMinesDuo()
- SetTimer(AddGear(2920, 1448, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2985, 1338, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(3005, 1302, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(3030, 1270, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(3046, 1257, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2954, 1400, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2967, 1385, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2849, 1449, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2811, 1436, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2773, 1411, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2732, 1390, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2700, 1362, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2642, 1321, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2172, 1417, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2190, 1363, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2219, 1332, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(1201, 1207, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(1247, 1205, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(1295, 1212, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(1356, 1209, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(1416, 1201, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(1466, 1201, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(1678, 1198, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(1738, 1198, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(1796, 1198, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(1637, 1217, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(1519, 1213, gtMine, 0, 0, 0, 0), 5000)
-end
-
-function AfterPastFlowerAnim()
- PlaceMinesDuo()
- AddEvent(CheckDensePit, {}, DoDensePit, {}, 0)
- AddEvent(CheckTookGirder1, {}, DoTookGirder1, {}, 0)
- AddEvent(CheckTookGirder2, {}, DoTookGirder2, {}, 0)
- SetGearMessage(leaks, 0)
- SetGearMessage(dense, 0)
- TurnTimeLeft = 0
- ShowMission(loc("The Journey Back"), loc("The Savior"), loc("Get Dense Cloud out of the pit!"), 1, 5000)
-end
-
-function SkipPastFlowerAnim()
- AnimSetGearPosition(dense, 2656, 1842)
- AnimSwitchHog(dense)
- AnimWait(dense, 1)
- AddFunction({func = HideHedge, args = {cyborg}})
-end
-
-function AfterOutPitAnim()
- SetupCourseDuo()
- RestoreHedge(cannibals[5])
- AddAmmo(cannibals[5], amDEagle, 0)
- HideHedge(cannibals[5])
- AddEvent(CheckTookFire, {}, DoTookFire, {}, 0)
- SetGearMessage(leaks, 0)
- SetGearMessage(dense, 0)
- TurnTimeLeft = 0
- ShowMission(loc("The Journey Back"), loc("They never learn"), loc("Free Dense Cloud and continue the mission!"), 1, 5000)
-end
-
-function SkipOutPitAnim()
- AnimSetGearPosition(dense, unpack(midDensePosDuo))
- AnimSwitchHog(dense)
- AnimWait(dense, 1)
- AddFunction({func = HideHedge, args = {cyborg}})
-end
-
-function RestoreCyborg(x, y, xx, yy)
- RestoreHedge(cyborg)
- RestoreHedge(princess)
- AnimOutOfNowhere(cyborg, x, y)
- AnimOutOfNowhere(princess, xx, yy)
- HogTurnLeft(princess, false)
- return true
-end
-
-function RestoreCyborgOnly(x, y)
- RestoreHedge(cyborg)
- SetState(cyborg, 0)
- AnimOutOfNowhere(cyborg, x, y)
- return true
-end
-
-function TargetPrincess()
- ParseCommand("setweap " .. string.char(amDEagle))
- SetGearMessage(cyborg, gmUp)
- return true
-end
-
-function HideCyborg()
- HideHedge(cyborg)
- HideHedge(princess)
-end
-
-function HideCyborgOnly()
- HideHedge(cyborg)
-end
-
-function SetupKillRoom()
- PlaceGirder(2342, 1814, 2)
- PlaceGirder(2294, 1783, 0)
- PlaceGirder(2245, 1814, 2)
-end
-
-function SetupCourseDuo()
- PlaceGirder(1083, 1152, 6)
- PlaceGirder(1087, 1150, 6)
- PlaceGirder(1133, 1155, 0)
- PlaceGirder(1135, 1152, 0)
- PlaceGirder(1135, 1078, 0)
- PlaceGirder(1087, 1016, 2)
- PlaceGirder(1018, 921, 5)
- PlaceGirder(1016, 921, 5)
- PlaceGirder(962, 782, 6)
- PlaceGirder(962, 662, 2)
- PlaceGirder(962, 661, 2)
- PlaceGirder(962, 650, 2)
- PlaceGirder(962, 630, 2)
- PlaceGirder(1033, 649, 0)
- PlaceGirder(952, 650, 0)
-
- fireCrate = SpawnAmmoCrate(1846, 1100, amFirePunch)
- SpawnUtilityCrate(1900, 1100, amPickHammer)
- SpawnAmmoCrate(950, 674, amDynamite)
- SpawnUtilityCrate(994, 825, amRope)
- SpawnUtilityCrate(570, 1357, amLowGravity)
-end
-
-function DumpMines()
- SetTimer(AddGear(2261, 1835, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2280, 1831, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2272, 1809, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2290, 1815, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2278, 1815, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2307, 1811, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2286, 1820, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2309, 1813, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2303, 1822, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2317, 1827, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2312, 1816, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2316, 1812, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2307, 1802, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2276, 1818, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2284, 1816, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2292, 1811, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2295, 1814, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2306, 1811, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2292, 1815, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2314, 1815, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2286, 1813, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2275, 1813, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2269, 1814, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2273, 1812, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2300, 1808, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2322, 1812, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2323, 1813, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2311, 1811, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2303, 1809, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2287, 1808, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2282, 1808, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2277, 1809, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2296, 1809, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(2314, 1818, gtMine, 0, 0, 0, 0), 5000)
-end
-
-function SetupAnimRefusedDied()
- SetupAnimAcceptedDied()
- table.insert(startAnim, {func = AnimSay, args = {leaks, loc("I just wonder where Ramon and Spiky disappeared..."), SAY_THINK, 6000}})
-end
-
-function SetupAnimAttacked()
- SetupAnimAcceptedDied()
- startAnim = {}
- table.insert(startAnim, {func = AnimWait, args = {leaks, 3000}})
- table.insert(startAnim, {func = AnimTurn, args = {leaks, "Left"}})
- table.insert(startAnim, {func = AnimSay, args = {leaks, loc("I wonder where Dense Cloud is..."), SAY_THINK, 4000}})
- table.insert(startAnim, {func = AnimSay, args = {leaks, loc("He must be in the village already."), SAY_THINK, 4000}})
- table.insert(startAnim, {func = AnimSay, args = {leaks, loc("I'd better get going myself."), SAY_THINK, 4000}})
-
- midAnim = {}
- table.insert(midAnim, {func = AnimWait, args = {leaks, 500}})
- table.insert(midAnim, {func = AnimCustomFunction, swh = false, args = {leaks, RestoreCyborg, {1300, 1200, 1390, 1200}}})
- table.insert(midAnim, {func = AnimSwitchHog, args = {cyborg}})
- table.insert(midAnim, {func = AnimCustomFunction, args = {cyborg, TargetPrincess, {}}})
- table.insert(midAnim, {func = AnimSay, args = {cyborg, loc("Welcome, Leaks A Lot!"), SAY_SAY, 3000}})
- table.insert(midAnim, {func = AnimSay, args = {cyborg, loc("I want to play a game..."), SAY_SAY, 3000}})
- table.insert(midAnim, {func = AnimSay, args = {princess, loc("Help me, please!!!"), SAY_SHOUT, 3000}})
- table.insert(midAnim, {func = AnimSay, args = {cyborg, loc("If you can get that crate fast enough, your beloved \"princess\" may go free."), SAY_SAY, 7000}})
- table.insert(midAnim, {func = AnimSay, args = {cyborg, loc("However, if you fail to do so, she dies a most violent death! Muahahaha!"), SAY_SAY, 8000}})
- table.insert(midAnim, {func = AnimSay, args = {cyborg, loc("Good luck...or else!"), SAY_SAY, 4000}})
- table.insert(midAnim, {func = AnimTeleportGear, args = {leaks, 2656, 1842}})
- table.insert(midAnim, {func = AnimCustomFunction, args = {cyborg, HideCyborg, {}}, swh = false})
- table.insert(midAnim, {func = AnimSay, args = {leaks, loc("Hey! This is cheating!"), SAY_SHOUT, 4000}})
- AddSkipFunction(midAnim, SkipMidAnimAlone, {})
-end
-
-function SetupAnimAcceptedDied()
- table.insert(startAnimAD, {func = AnimWait, args = {leaks, 3000}})
- table.insert(startAnimAD, {func = AnimTurn, args = {leaks, "Left"}})
- table.insert(startAnimAD, {func = AnimSay, args = {leaks, loc("I need to get to the other side of this island, fast!"), SAY_THINK, 5000}})
- table.insert(startAnimAD, {func = AnimSay, args = {leaks, loc("With Dense Cloud on the land of shadows, I'm the village's only hope..."), SAY_THINK, 7000}})
-
- table.insert(midAnimAD, {func = AnimWait, args = {leaks, 500}})
- table.insert(midAnimAD, {func = AnimCustomFunction, swh = false, args = {leaks, RestoreCyborg, {1300, 1200, 1390, 1200}}})
- table.insert(midAnimAD, {func = AnimSwitchHog, args = {cyborg}})
- table.insert(midAnimAD, {func = AnimCustomFunction, args = {cyborg, TargetPrincess, {}}})
- table.insert(midAnimAD, {func = AnimSay, args = {cyborg, loc("Welcome, Leaks A Lot!"), SAY_SAY, 3000}})
- table.insert(midAnimAD, {func = AnimSay, args = {cyborg, loc("I want to play a game..."), SAY_SAY, 3000}})
- table.insert(midAnimAD, {func = AnimSay, args = {princess, loc("Help me, please!!!"), SAY_SHOUT, 3000}})
- table.insert(midAnimAD, {func = AnimSay, args = {cyborg, loc("If you can get that crate fast enough, your beloved \"princess\" may go free."), SAY_SAY, 7000}})
- table.insert(midAnimAD, {func = AnimSay, args = {cyborg, loc("However, if you fail to do so, she dies a most violent death, just like your friend! Muahahaha!"), SAY_SAY, 8000}})
- table.insert(midAnimAD, {func = AnimSay, args = {cyborg, loc("Good luck...or else!"), SAY_SAY, 4000}})
- table.insert(midAnimAD, {func = AnimTeleportGear, args = {leaks, 2656, 1842}})
- table.insert(midAnimAD, {func = AnimCustomFunction, args = {cyborg, HideCyborg, {}}, swh = false})
- table.insert(midAnimAD, {func = AnimSay, args = {leaks, loc("Hey! This is cheating!"), SAY_SHOUT, 4000}})
- AddSkipFunction(midAnimAD, SkipMidAnimAlone, {})
-
- table.insert(failAnimAD, {func = AnimCustomFunction, swh = false, args = {leaks, RestoreCyborg, {2299, 1687, 2294, 1841}}})
- table.insert(failAnimAD, {func = AnimTeleportGear, args = {leaks, 2090, 1841}})
- table.insert(failAnimAD, {func = AnimCustomFunction, swh = false, args = {cyborg, SetupKillRoom, {}}})
- table.insert(failAnimAD, {func = AnimTurn, swh = false, args = {cyborg, "Left"}})
- table.insert(failAnimAD, {func = AnimTurn, swh = false, args = {princess, "Left"}})
- table.insert(failAnimAD, {func = AnimTurn, swh = false, args = {leaks, "Right"}})
- table.insert(failAnimAD, {func = AnimWait, args = {cyborg, 1000}})
- table.insert(failAnimAD, {func = AnimSay, args = {cyborg, loc("You have failed to complete your task, young one!"), SAY_SAY, 6000}})
- table.insert(failAnimAD, {func = AnimSay, args = {cyborg, loc("It's time you learned that your actions have consequences!"), SAY_SAY, 7000}})
- table.insert(failAnimAD, {func = AnimSay, args = {princess, loc("No! Please, help me!"), SAY_SAY, 4000}})
- table.insert(failAnimAD, {func = AnimSwitchHog, args = {cyborg}})
- table.insert(failAnimAD, {func = AnimCustomFunction, args = {cyborg, DumpMines, {}}})
- table.insert(failAnimAD, {func = AnimCustomFunction, args = {cyborg, KillPrincess, {}}})
- table.insert(failAnimAD, {func = AnimWait, args = {cyborg, 12000}})
- table.insert(failAnimAD, {func = AnimSay, args = {leaks, loc("No! What have I done?! What have YOU done?!"), SAY_SHOUT, 6000}})
-
- table.insert(endAnimAD, {func = AnimCustomFunction, swh = false, args = {leaks, RestoreCyborg, {437, 1700, 519, 1722}}})
- table.insert(endAnimAD, {func = AnimTurn, swh = false, args = {cyborg, "Right"}})
- table.insert(endAnimAD, {func = AnimTurn, swh = false, args = {princess, "Right"}})
- table.insert(endAnimAD, {func = AnimSay, args = {princess, loc("Help me, Leaks!"), SAY_SHOUT, 3000}})
- table.insert(endAnimAD, {func = AnimSay, args = {leaks, loc("But you said you'd let her go!"), SAY_SHOUT, 5000}})
- table.insert(endAnimAD, {func = AnimSay, args = {cyborg, loc("And you believed me? Oh, god, that's cute!"), SAY_SHOUT, 7000}})
- table.insert(endAnimAD, {func = AnimSay, args = {leaks, loc("I won't let you kill her!"), SAY_SHOUT, 4000}})
- AddSkipFunction(endAnimAD, SkipEndAnimAlone, {})
-
- table.insert(endFailAnim, {func = AnimCaption, args = {leaks, loc("Leaks A Lot, depressed for killing his loved one, failed to save the village..."), 3000}})
-
- table.insert(winAnimAD, {func = AnimCustomFunction, args = {princess, CondNeedToTurn, {leaks, princess}}})
- table.insert(winAnimAD, {func = AnimSay, args = {princess, loc("Thank you, oh, thank you, Leaks A Lot!"), SAY_SAY, 5000}})
- table.insert(winAnimAD, {func = AnimSay, args = {princess, loc("How can I ever repay you for saving my life?"), SAY_SAY, 6000}})
- table.insert(winAnimAD, {func = AnimSay, args = {leaks, loc("There's nothing more satisfying for me than seeing you share your beauty with the world every morning, my princess!"), SAY_SAY, 10000}})
- table.insert(winAnimAD, {func = AnimSay, args = {leaks, loc("Let's go home!"), SAY_SAY, 3000}})
- table.insert(winAnimAD, {func = AnimCaption, args = {leaks, loc("And so they discovered that cyborgs weren't invulnerable..."), 2000}})
-
- startAnim = startAnimAD
- midAnim = midAnimAD
- failAnim = failAnimAD
- endAnim = endAnimAD
- endFailAnim = endFailAnimAD
- winAnim = winAnimAD
-end
-
-function SetupAnimAcceptedLived()
- table.insert(startAnimAL, {func = AnimWait, args = {leaks, 3000}})
- table.insert(startAnimAL, {func = AnimCustomFunction, args = {dense, CondNeedToTurn, {leaks, dense}}})
- table.insert(startAnimAL, {func = AnimSay, args = {leaks, loc("All right, we just need to get to the other side of the island!"), SAY_SAY, 8000}})
- table.insert(startAnimAL, {func = AnimSay, args = {dense, loc("We have no time to waste..."), SAY_SAY, 4000}})
- table.insert(startAnimAL, {func = AnimSwitchHog, args = {leaks}})
- AddSkipFunction(startAnimAL, SkipStartAnim, {})
-
- table.insert(pastFlowerAnimAL, {func = AnimCustomFunction, args = {dense, RestoreCyborgOnly, {unpack(startCyborgPosDuo)}}, swh = false})
- table.insert(pastFlowerAnimAL, {func = AnimTurn, args = {cyborg, "Right"}})
- table.insert(pastFlowerAnimAL, {func = AnimSay, args = {cyborg, loc("Well, well! Isn't that the cutest thing you've ever seen?"), SAY_SAY, 7000}})
- table.insert(pastFlowerAnimAL, {func = AnimSay, args = {cyborg, loc("Two little hogs cooperating, getting past obstacles..."), SAY_SAY, 7000}})
- table.insert(pastFlowerAnimAL, {func = AnimSay, args = {cyborg, loc("Let me test your skills a little, will you?"), SAY_SAY, 6000}})
- table.insert(pastFlowerAnimAL, {func = AnimTeleportGear, args = {cyborg, 2456, 1842}})
- table.insert(pastFlowerAnimAL, {func = AnimTeleportGear, args = {dense, 2656, 1842}})
- table.insert(pastFlowerAnimAL, {func = AnimCustomFunction, args = {dense, CondNeedToTurn, {cyborg, dense}}})
- table.insert(pastFlowerAnimAL, {func = AnimSay, args = {dense, loc("Why are you doing this?"), SAY_SAY, 4000}})
- table.insert(pastFlowerAnimAL, {func = AnimSay, args = {cyborg, loc("To help you, of course!"), SAY_SAY, 4000}})
- table.insert(pastFlowerAnimAL, {func = AnimSwitchHog, args = {dense}})
- table.insert(pastFlowerAnimAL, {func = AnimDisappear, swh = false, args = {cyborg, 3781, 1583}})
- table.insert(pastFlowerAnimAL, {func = AnimCustomFunction, swh = false, args = {cyborg, HideCyborgOnly, {}}})
- AddSkipFunction(pastFlowerAnimAL, SkipPastFlowerAnim, {})
-
- table.insert(outPitAnimAL, {func = AnimCustomFunction, args = {dense, RestoreCyborgOnly, {unpack(midCyborgPosDuo)}}, swh = false})
- table.insert(outPitAnimAL, {func = AnimTurn, args = {cyborg, "Right"}})
- table.insert(outPitAnimAL, {func = AnimTeleportGear, args = {dense, unpack(midDensePosDuo)}})
- table.insert(outPitAnimAL, {func = AnimTurn, args = {dense, "Left"}})
- table.insert(outPitAnimAL, {func = AnimSay, args = {dense, loc("OH, COME ON!"), SAY_SHOUT, 3000}})
- table.insert(outPitAnimAL, {func = AnimSay, args = {cyborg, loc("Let's see what your comrade does now!"), SAY_SAY, 5000}})
- table.insert(outPitAnimAL, {func = AnimSwitchHog, args = {dense}})
- table.insert(outPitAnimAL, {func = AnimDisappear, swh = false, args = {cyborg, 3781, 1583}})
- table.insert(outPitAnimAL, {func = AnimCustomFunction, swh = false, args = {cyborg, HideCyborgOnly, {}}})
- AddSkipFunction(outPitAnimAL, SkipOutPitAnim, {})
-
- table.insert(endAnim, {func = AnimCustomFunction, swh = false, args = {leaks, RestoreCyborg, {437, 1700, 519, 1722}}})
- table.insert(endAnim, {func = AnimTeleportGear, args = {leaks, 763, 1760}})
- table.insert(endAnim, {func = AnimTeleportGear, args = {dense, 835, 1519}})
- table.insert(endAnim, {func = AnimTurn, swh = false, args = {leaks, "Left"}})
- table.insert(endAnim, {func = AnimTurn, swh = false, args = {dense, "Left"}})
- table.insert(endAnim, {func = AnimTurn, swh = false, args = {cyborg, "Right"}})
- table.insert(endAnim, {func = AnimTurn, swh = false, args = {princess, "Right"}})
- table.insert(endAnim, {func = AnimSay, args = {princess, loc("Help me, please!"), SAY_SHOUT, 3000}})
- table.insert(endAnim, {func = AnimSay, args = {leaks, loc("What are you doing? Let her go!"), SAY_SHOUT, 5000}})
- table.insert(endAnim, {func = AnimSay, args = {cyborg, loc("Yeah? Watcha gonna do? Cry?"), SAY_SHOUT, 5000}})
- table.insert(endAnim, {func = AnimSay, args = {leaks, loc("We won't let you hurt her!"), SAY_SHOUT, 4000}})
- AddSkipFunction(endAnim, SkipEndAnimDuo, {})
-
- table.insert(endFailAnim, {func = AnimCaption, args = {leaks, loc("Leaks A Lot, depressed for killing his loved one, failed to save the village..."), 3000}})
-
- table.insert(winAnim, {func = AnimCustomFunction, args = {princess, CondNeedToTurn, {leaks, princess}}})
- table.insert(winAnim, {func = AnimSay, args = {princess, loc("Thank you, oh, thank you, my heroes!"), SAY_SAY, 5000}})
- table.insert(winAnim, {func = AnimSay, args = {princess, loc("How can I ever repay you for saving my life?"), SAY_SAY, 6000}})
- table.insert(winAnim, {func = AnimSay, args = {leaks, loc("There's nothing more satisfying to us than seeing you share your beauty..."), SAY_SAY, 7000}})
- table.insert(winAnim, {func = AnimSay, args = {leaks, loc("... share your beauty with the world every morning, my princess!"), SAY_SAY, 7000}})
- table.insert(winAnim, {func = AnimSay, args = {leaks, loc("Let's go home!"), SAY_SAY, 3000}})
- table.insert(winAnim, {func = AnimCaption, args = {leaks, loc("And so they discovered that cyborgs weren't invulnerable..."), 2000}})
-
- startAnim = startAnimAL
- pastFlowerAnim = pastFlowerAnimAL
- outPitAnim = outPitAnimAL
-end
-
-function SetupAnimRefusedLived()
- table.insert(startAnimRL, {func = AnimWait, args = {leaks, 3000}})
- table.insert(startAnimRL, {func = AnimCustomFunction, args = {dense, CondNeedToTurn, {leaks, dense}}})
- table.insert(startAnimRL, {func = AnimSay, args = {leaks, loc("All right, we just need to get to the other side of the island!"), SAY_SAY, 7000}})
- table.insert(startAnimRL, {func = AnimSay, args = {dense, loc("Dude, can you see Ramon and Spiky?"), SAY_SAY, 5000}})
- table.insert(startAnimRL, {func = AnimSay, args = {leaks, loc("No...I wonder where they disappeared?!"), SAY_SAY, 5000}})
- AddSkipFunction(startAnimRL, SkipStartAnim, {})
-
- table.insert(pastFlowerAnimRL, {func = AnimCustomFunction, args = {dense, RestoreCyborgOnly, {unpack(startCyborgPosDuo)}}, swh = false})
- table.insert(pastFlowerAnimRL, {func = AnimTurn, args = {cyborg, "Right"}})
- table.insert(pastFlowerAnimRL, {func = AnimSay, args = {cyborg, loc("Well, well! Isn't that the cutest thing you've ever seen?"), SAY_SAY, 7000}})
- table.insert(pastFlowerAnimRL, {func = AnimSay, args = {cyborg, loc("Two little hogs cooperating, getting past obstacles..."), SAY_SAY, 7000}})
- table.insert(pastFlowerAnimRL, {func = AnimSay, args = {cyborg, loc("Let me test your skills a little, will you?"), SAY_SAY, 6000}})
- table.insert(pastFlowerAnimRL, {func = AnimTeleportGear, args = {cyborg, 2456, 1842}})
- table.insert(pastFlowerAnimRL, {func = AnimTeleportGear, args = {dense, 2656, 1842}})
- table.insert(pastFlowerAnimRL, {func = AnimCustomFunction, args = {dense, CondNeedToTurn, {cyborg, dense}}})
- table.insert(pastFlowerAnimRL, {func = AnimSay, args = {dense, loc("Why are you doing this?"), SAY_SAY, 4000}})
- table.insert(pastFlowerAnimRL, {func = AnimSay, args = {cyborg, loc("You couldn't possibly believe that after refusing my offer I'd just let you go!"), SAY_SAY, 9000}})
- table.insert(pastFlowerAnimRL, {func = AnimSay, args = {cyborg, loc("You're funny!"), SAY_SAY, 4000}})
- table.insert(pastFlowerAnimRL, {func = AnimSwitchHog, args = {dense}})
- table.insert(pastFlowerAnimRL, {func = AnimDisappear, swh = false, args = {cyborg, 3781, 1583}})
- table.insert(pastFlowerAnimRL, {func = AnimCustomFunction, swh = false, args = {cyborg, HideCyborgOnly, {}}})
- AddSkipFunction(pastFlowerAnimRL, SkipPastFlowerAnim, {})
-
- table.insert(outPitAnimRL, {func = AnimCustomFunction, args = {dense, RestoreCyborgOnly, {unpack(midCyborgPosDuo)}}, swh = false})
- table.insert(outPitAnimRL, {func = AnimTurn, args = {cyborg, "Right"}})
- table.insert(outPitAnimRL, {func = AnimTeleportGear, args = {dense, unpack(midDensePosDuo)}})
- table.insert(outPitAnimRL, {func = AnimTurn, args = {dense, "Left"}})
- table.insert(outPitAnimRL, {func = AnimSay, args = {dense, loc("OH, COME ON!"), SAY_SHOUT, 3000}})
- table.insert(outPitAnimRL, {func = AnimSay, args = {cyborg, loc("Let's see what your comrade does now!"), SAY_SAY, 5000}})
- table.insert(outPitAnimRL, {func = AnimSwitchHog, args = {dense}})
- table.insert(outPitAnimRL, {func = AnimDisappear, swh = false, args = {cyborg, 3781, 1583}})
- table.insert(outPitAnimRL, {func = AnimCustomFunction, swh = false, args = {cyborg, HideCyborgOnly, {}}})
- AddSkipFunction(outPitAnimRL, SkipOutPitAnim, {})
-
- table.insert(endAnim, {func = AnimCustomFunction, args = {leaks, RestoreCyborg, {437, 1700, 519, 1722}}})
- table.insert(endAnim, {func = AnimTeleportGear, args = {leaks, 763, 1760}})
- table.insert(endAnim, {func = AnimTeleportGear, args = {dense, 835, 1519}})
- table.insert(endAnim, {func = AnimTurn, swh = false, args = {leaks, "Left"}})
- table.insert(endAnim, {func = AnimTurn, swh = false, args = {dense, "Left"}})
- table.insert(endAnim, {func = AnimTurn, swh = false, args = {cyborg, "Right"}})
- table.insert(endAnim, {func = AnimTurn, swh = false, args = {princess, "Right"}})
- table.insert(endAnim, {func = AnimSay, args = {princess, loc("Help me, please!"), SAY_SHOUT, 3000}})
- table.insert(endAnim, {func = AnimSay, args = {leaks, loc("What are you doing? Let her go!"), SAY_SHOUT, 5000}})
- table.insert(endAnim, {func = AnimSay, args = {cyborg, loc("Yeah? Watcha gonna do? Cry?"), SAY_SHOUT, 5000}})
- table.insert(endAnim, {func = AnimSay, args = {leaks, loc("We won't let you hurt her!"), SAY_SHOUT, 4000}})
- AddSkipFunction(endAnim, SkipEndAnimDuo, {})
-
- table.insert(endFailAnim, {func = AnimCaption, args = {leaks, loc("Leaks A Lot, depressed for killing his loved one, failed to save the village..."), 3000}})
-
- table.insert(winAnim, {func = AnimCustomFunction, args = {princess, CondNeedToTurn, {leaks, princess}}})
- table.insert(winAnim, {func = AnimSay, args = {princess, loc("Thank you, oh, thank you, my heroes!"), SAY_SAY, 5000}})
- table.insert(winAnim, {func = AnimSay, args = {princess, loc("How can I ever repay you for saving my life?"), SAY_SAY, 6000}})
- table.insert(winAnim, {func = AnimSay, args = {leaks, loc("There's nothing more satisfying to us than seeing you share your beauty with the world every morning, my princess!"), SAY_SAY, 10000}})
- table.insert(winAnim, {func = AnimSay, args = {leaks, loc("Let's go home!"), SAY_SAY, 3000}})
- table.insert(winAnim, {func = AnimCaption, args = {leaks, loc("And so they discovered that cyborgs weren't invulnerable..."), 2000}})
-
- startAnim = startAnimRL
- pastFlowerAnim = pastFlowerAnimRL
- outPitAnim = outPitAnimRL
-end
-
-function KillPrincess()
- ParseCommand("teamgone " .. loc("Cannibal Sentry"))
- TurnTimeLeft = 0
-end
---/////////////////////////////Misc Functions////////////////////////
-
-function HideHedge(hedge)
- if hedgeHidden[hedge] ~= true then
- HideHog(hedge)
- hedgeHidden[hedge] = true
- end
-end
-
-function RestoreHedge(hedge)
- if hedgeHidden[hedge] == true then
- RestoreHog(hedge)
- hedgeHidden[hedge] = false
- end
-end
-
-function CondNeedToTurn(hog1, hog2)
- xl, xd = GetX(hog1), GetX(hog2)
- if xl > xd then
- AnimInsertStepNext({func = AnimTurn, args = {hog1, "Left"}})
- AnimInsertStepNext({func = AnimTurn, args = {hog2, "Right"}})
- elseif xl < xd then
- AnimInsertStepNext({func = AnimTurn, args = {hog2, "Left"}})
- AnimInsertStepNext({func = AnimTurn, args = {hog1, "Right"}})
- end
-end
-
-function SetupPlaceAlone()
- ------ AMMO CRATE LIST ------
- --SpawnAmmoCrate(3122, 994, amShotgun)
- SpawnAmmoCrate(3124, 952, amBaseballBat)
- SpawnAmmoCrate(2508, 1110, amFirePunch)
- ------ UTILITY CRATE LIST ------
- blowCrate = SpawnUtilityCrate(3675, 1480, amBlowTorch)
- gravityCrate = SpawnUtilityCrate(3448, 1349, amLowGravity)
- SpawnUtilityCrate(3212, 1256, amGirder)
- SpawnUtilityCrate(3113, 911, amParachute)
- sniperCrate = SpawnAmmoCrate(784, 1715, amSniperRifle)
- ------ MINE LIST ------
- SetTimer(AddGear(3328, 1399, gtMine, 0, 0, 0, 0), 3000)
- SetTimer(AddGear(3028, 1262, gtMine, 0, 0, 0, 0), 3000)
- SetTimer(AddGear(2994, 1274, gtMine, 0, 0, 0, 0), 3000)
- SetTimer(AddGear(2956, 1277, gtMine, 0, 0, 0, 0), 3000)
- SetTimer(AddGear(2925, 1282, gtMine, 0, 0, 0, 0), 3000)
- SetTimer(AddGear(2838, 1276, gtMine, 0, 0, 0, 0), 3000)
- SetTimer(AddGear(2822, 1278, gtMine, 0, 0, 0, 0), 3000)
- SetTimer(AddGear(2786, 1283, gtMine, 0, 0, 0, 0), 3000)
- SetTimer(AddGear(2766, 1270, gtMine, 0, 0, 0, 0), 3000)
- SetTimer(AddGear(2749, 1231, gtMine, 0, 0, 0, 0), 3000)
- SetTimer(AddGear(2717, 1354, gtMine, 0, 0, 0, 0), 3000)
- SetTimer(AddGear(2167, 1330, gtMine, 0, 0, 0, 0), 3000)
- SetTimer(AddGear(2201, 1321, gtMine, 0, 0, 0, 0), 3000)
- SetTimer(AddGear(2239, 1295, gtMine, 0, 0, 0, 0), 3000)
-
- AnimSetGearPosition(leaks, 3781, 1583)
- --AnimSetGearPosition(leaks, 1650, 1583)
- AddAmmo(cannibals[1], amShotgun, 100)
- AddAmmo(leaks, amSwitch, 0)
-end
-
-function SetupPlaceDuo()
- PlaceCratesDuo()
- AnimSetGearPosition(leaks, unpack(startLeaksPosDuo))
- AnimSetGearPosition(dense, unpack(startDensePosDuo))
-end
-
-function SetupEventsDuo()
- AddEvent(CheckPastFlower, {}, DoPastFlower, {}, 0)
- AddEvent(CheckLeaksDead, {}, DoLeaksDead, {}, 0)
- AddEvent(CheckDenseDead, {}, DoDenseDead, {}, 0)
- AddEvent(CheckTookSniper2, {}, DoTookSniper2, {}, 0)
-end
-
-function SetupEventsAlone()
- AddEvent(CheckLeaksDead, {}, DoLeaksDead, {}, 0)
- AddEvent(CheckTookBlowTorch, {}, DoTookBlowTorch, {}, 0)
- AddEvent(CheckTookLowGravity, {}, DoTookLowGravity, {}, 0)
- AddEvent(CheckOnBridge, {}, DoOnBridge, {}, 0)
-end
-
-function StartMission()
- if m2DenseDead == 1 then
- DeleteGear(dense)
- if m2Choice == choiceAccepted then
- SetupAnimAcceptedDied()
- elseif m2Choice == choiceRefused then
- SetupAnimRefusedDied()
- else
- SetupAnimAttacked()
- end
- SetupPlaceAlone()
- SetupEventsAlone()
- AddAnim(startAnim)
- AddFunction({func = AfterStartAnim, args = {}})
- else
- if m2Choice == choiceAccepted then
- SetupAnimAcceptedLived()
- else
- SetupAnimRefusedLived()
- end
- SetupPlaceDuo()
- SetupEventsDuo()
- AddAnim(startAnim)
- AddFunction({func = AfterStartAnim, args = {}})
- end
- HideHedge(cyborg)
- HideHedge(princess)
- for i = 5, 8 do
- HideHedge(cannibals[i])
- end
-
-end
-
-function SetupCourse()
-
- ------ GIRDER LIST ------
- PlaceGirder(1091, 1150, 6)
- PlaceGirder(1091, 989, 6)
- PlaceGirder(1091, 829, 6)
- PlaceGirder(1091, 669, 6)
- PlaceGirder(1091, 668, 6)
- PlaceGirder(1091, 669, 6)
- PlaceGirder(1088, 667, 6)
- PlaceGirder(1091, 658, 6)
- PlaceGirder(1091, 646, 6)
- PlaceGirder(1091, 607, 6)
- PlaceGirder(1091, 571, 6)
- PlaceGirder(1376, 821, 6)
- PlaceGirder(1145, 1192, 1)
- PlaceGirder(1169, 1076, 3)
- PlaceGirder(1351, 1082, 4)
- PlaceGirder(1469, 987, 3)
- PlaceGirder(1386, 951, 0)
- PlaceGirder(1465, 852, 3)
- PlaceGirder(1630, 913, 0)
- PlaceGirder(1733, 856, 7)
- PlaceGirder(1688, 713, 5)
- PlaceGirder(1556, 696, 2)
- PlaceGirder(1525, 696, 2)
- PlaceGirder(1457, 697, 2)
- PlaceGirder(1413, 700, 3)
- PlaceGirder(1270, 783, 2)
- PlaceGirder(1207, 825, 2)
- PlaceGirder(1135, 775, 1)
-
- ------ UTILITY CRATE LIST ------
- SpawnUtilityCrate(1590, 628, amParachute)
- SpawnAmmoCrate(1540, 100, amDynamite)
- SpawnUtilityCrate(2175, 1815, amLowGravity)
- SpawnUtilityCrate(2210, 1499, amFirePunch)
- girderCrate = SpawnUtilityCrate(2300, 1663, amGirder)
- SpawnUtilityCrate(610, 1394, amPickHammer)
-
- ------ BARREL LIST ------
- SetHealth(AddGear(1148, 736, gtExplosives, 0, 0, 0, 0), 20)
-
-end
-
-function PlaceCourseMines()
- SetTimer(AddGear(1215, 1193, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(1259, 1199, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(1310, 1198, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(1346, 1196, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(1383, 1192, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(1436, 1196, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(1487, 1199, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(1651, 1209, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(1708, 1209, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(1759, 1190, gtMine, 0, 0, 0, 0), 5000)
- SetTimer(AddGear(1815, 1184, gtMine, 0, 0, 0, 0), 5000)
-end
-
-
---////////////////////////////Event Functions////////////////////////
-function CheckTookFire()
- return fireTaken
-end
-
-function DoTookFire()
- AddAmmo(leaks, amFirePunch, 100)
-end
-
-function CheckTookGirder1()
- return girder1Taken
-end
-
-function CheckTookGirder2()
- return girder2Taken
-end
-
-function DoTookGirder1()
- AddAmmo(dense, amGirder, 2)
-end
-
-function DoTookGirder2()
- AddAmmo(dense, amGirder, 3)
-end
-
-function CheckDensePit()
- return GetY(dense) < 1250 and StoppedGear(dense)
-end
-
-function DoDensePit()
- TurnTimeLeft = 0
- RestoreHedge(cyborg)
- AnimWait(cyborg, 1)
- AddFunction({func = AddAnim, args = {outPitAnim}})
- AddFunction({func = AddFunction, args = {{func = AfterOutPitAnim, args = {}}}})
-end
-
-function CheckPastFlower()
- if denseDead == true or leaksDead == true then
- return false
- end
- return (GetX(dense) < startEventXDuo and StoppedGear(dense))
- or (GetX(leaks) < startEventXDuo and StoppedGear(leaks))
-end
-
-function DoPastFlower()
- TurnTimeLeft = 0
- RestoreHedge(cyborg)
- AnimWait(cyborg, 1)
- AddFunction({func = AddAnim, args = {pastFlowerAnim}})
- AddFunction({func = AddFunction, args = {{func = AfterPastFlowerAnim, args = {}}}})
-end
-
-
-function CheckLeaksDead()
- return leaksDead
-end
-
-function DoLeaksDead()
- AddCaption(loc("The village, unprepared, was destroyed by the cyborgs..."))
- ParseCommand("teamgone " .. loc("Natives"))
-end
-
-function CheckDenseDead()
- return denseDead
-end
-
-function DoDenseDead()
- AddCaption(loc("The village, unprepared, was destroyed by the cyborgs..."))
- ParseCommand("teamgone " .. loc("Natives"))
-end
-
-function CheckTookBlowTorch()
- return blowTaken
-end
-
-function DoTookBlowTorch()
- ShowMission(loc("The Journey Back"), loc("The Tunnel Maker"), loc("Hint: Select the BlowTorch, aim and press [Fire]. Press [Fire] again to stop.|Don't blow up the crate."), 0, 6000)
-end
-
-function CheckTookLowGravity()
- return gravityTaken
-end
-
-function DoTookLowGravity()
- ShowMission(loc("The Journey Back"), loc("The Moonwalk"), loc("Hint: Select the LowGravity and press [Fire]."), 0, 6000)
-end
-
-function CheckOnBridge()
- return leaksDead == false and GetX(leaks) < 1651 and StoppedGear(leaks)
-end
-
-function DoOnBridge()
- TurnTimeLeft = 0
- RestoreHedge(cyborg)
- RestoreHedge(princess)
- AnimWait(cyborg, 1)
- AddFunction({func = AddAnim, args = {midAnim}})
- AddFunction({func = AddFunction, args = {{func = AfterMidAnimAlone, args = {}}}})
-end
-
-function CheckGirderTaken()
- return girderTaken
-end
-
-function DoGirderTaken()
- AddAmmo(leaks, amGirder, 2)
--- AddAmmo(leaks, amGirder, 3)
-end
-
-function CheckOnFirstGirder()
- return leaksDead == false and GetX(leaks) < 1160 and StoppedGear(leaks)
-end
-
-function DoOnFirstGirder()
- PlaceCourseMines()
- ShowMission(loc("The Journey Back"), loc("Slippery"), loc("You'd better watch your steps..."), 0, 4000)
-end
-
-function CheckTookSniper()
- return sniperTaken and StoppedGear(leaks)
-end
-
-function DoTookSniper()
- TurnTimeLeft = 0
- RestoreHedge(cyborg)
- RestoreHedge(princess)
- AnimWait(cyborg, 1)
- AddFunction({func = AddAnim, args = {endAnim}})
- AddFunction({func = AddFunction, args = {{func = AfterEndAnimAlone, args = {}}}})
-end
-
-function CheckTookSniper2()
- return sniperTaken and StoppedGear(leaks) and StoppedGear(dense)
-end
-
-function DoTookSniper2()
- TurnTimeLeft = 0
- RestoreHedge(cyborg)
- RestoreHedge(princess)
- AnimWait(cyborg, 1)
- AddFunction({func = AddAnim, args = {endAnim}})
- AddFunction({func = AddFunction, args = {{func = AfterEndAnimDuo, args = {}}}})
-end
-
-function CheckLost()
- return princessDead
-end
-
-function DoLost()
- AddAnim(endFailAnim)
- AddFunction({func = ParseCommand, args = {'teamgone ' .. loc('Natives')}})
-end
-
-function CheckWon()
- return cyborgDead and not princessDead
-end
-
-function DoWon()
- if progress and progress<3 then
- SaveCampaignVar("Progress", "3")
- end
- AddAnim(winAnim)
- AddFunction({func = FinishWon, args = {}})
-end
-
-function FinishWon()
- SwitchHog(leaks)
- ParseCommand("teamgone " .. loc("Cannibal Sentry"))
- ParseCommand("teamgone " .. loc("011101001"))
- TurnTimeLeft = 0
-end
-
-function CheckFailedCourse()
- return TurnsLeft == 0
-end
-
-function DoFailedCourse()
- TurnTimeLeft = 0
- RestoreHedge(cyborg)
- RestoreHedge(princess)
- AnimWait(cyborg, 1)
- AddFunction({func = AddAnim, args = {failAnim}})
- AddFunction({func = AddFunction, args = {{func = AfterMidFailAnim, args = {}}}})
-end
-
---////////////////////////////Main Functions/////////////////////////
-
-function onGameInit()
- Seed = 0
- GameFlags = gfSolidLand + gfDisableWind
- TurnTime = 40000
- CaseFreq = 0
- MinesNum = 0
- MinesTime = 3000
- Explosives = 0
- Delay = 5
- Map = "A_Classic_Fairytale_journey"
- Theme = "Nature"
-
- SuddenDeathTurns = 3000
-
- AddTeam(loc("Natives"), 29439, "Bone", "Island", "HillBilly", "cm_birdy")
- leaks = AddHog(loc("Leaks A Lot"), 0, 100, "Rambo")
- dense = AddHog(loc("Dense Cloud"), 0, 100, "RobinHood")
-
- AddTeam(loc("Cannibal Sentry"), 14483456, "Skull", "Island", "Pirate","cm_vampire")
- cannibals = {}
- for i = 1, 4 do
- cannibals[i] = AddHog(cannibalNames[i], 3, 40, "Zombi")
- AnimSetGearPosition(cannibals[i], unpack(cannibalPos[i]))
- end
-
- for i = 5, 8 do
- cannibals[i] = AddHog(cannibalNames[i], 3, 40, "Zombi")
- AnimSetGearPosition(cannibals[i], 0, 0)
- end
-
- AddTeam(loc("011101001"), 14483456, "ring", "UFO", "Robot", "cm_star")
- cyborg = AddHog(loc("Y3K1337"), 0, 200, "cyborg1")
- princess = AddHog(loc("Fell From Heaven"), 0, 200, "tiara")
-
- AnimSetGearPosition(dense, 0, 0)
- AnimSetGearPosition(leaks, 0, 0)
- AnimSetGearPosition(cyborg, 0, 0)
- AnimSetGearPosition(princess, 0, 0)
-
- AnimInit()
-end
-
-function onGameStart()
- progress = tonumber(GetCampaignVar("Progress"))
- m2Choice = tonumber(GetCampaignVar("M2Choice"))
- m2DenseDead = tonumber(GetCampaignVar("M2DenseDead"))
- m2RamonDead = tonumber(GetCampaignVar("M2RamonDead"))
- m2SpikyDead = tonumber(GetCampaignVar("M2SpikyDead"))
- StartMission()
-end
-
-function onGameTick()
- AnimUnWait()
- if ShowAnimation() == false then
- return
- end
- ExecuteAfterAnimations()
- CheckEvents()
-end
-
-function onGearDelete(gear)
- if gear == blowCrate then
- blowTaken = true
- elseif gear == fireCrate then
- fireTaken = true
- elseif gear == gravityCrate then
- gravityTaken = true
- elseif gear == leaks then
- leaksDead = true
- elseif gear == dense then
- denseDead = true
- elseif gear == cyborg then
- cyborgDead = true
- elseif gear == princess then
- princessDead = true
- elseif gear == girderCrate then
- girderTaken = true
- elseif gear == girderCrate1 then
- girder1Taken = true
- elseif gear == girderCrate2 then
- girder2Taken = true
- elseif gear == sniperCrate then
- sniperTaken = true
- else
- for i = 1, 4 do
- if gear == cannibals[i] then
- cannibalDead[i] = true
- end
- end
- end
-end
-
-function onAmmoStoreInit()
- SetAmmo(amBlowTorch, 0, 0, 0, 1)
- SetAmmo(amParachute, 0, 0, 0, 1)
- SetAmmo(amGirder, 0, 0, 0, 3)
- SetAmmo(amLowGravity, 0, 0, 0, 1)
- SetAmmo(amBaseballBat, 0, 0, 0, 1)
- SetAmmo(amFirePunch, 1, 0, 0, 1)
- SetAmmo(amSkip, 9, 0, 0, 0)
- SetAmmo(amSwitch, 9, 0, 0, 0)
- SetAmmo(amDEagle, 9, 0, 0, 0)
- SetAmmo(amRope, 0, 0, 0, 1)
- SetAmmo(amSniperRifle, 0, 0, 0, 1)
- SetAmmo(amDynamite, 0, 0, 0, 1)
- SetAmmo(amPickHammer, 0, 0, 0, 1)
-end
-
-function onNewTurn()
- if AnimInProgress() then
- TurnTimeLeft = -1
- elseif stage == endStage and CurrentHedgehog ~= leaks then
- AnimSwitchHog(leaks)
- SetGearMessage(leaks, 0)
- TurnTimeLeft = -1
- elseif GetHogTeamName(CurrentHedgehog) ~= loc("Natives") then
- for i = 1, 4 do
- if cannibalDead[i] ~= true then
- if GetX(cannibals[i]) < GetX(leaks) then
- HogTurnLeft(cannibals[i], false)
- else
- HogTurnLeft(cannibals[i], true)
- end
- end
- end
- SetInputMask(band(0xFFFFFFFF, bnot(gmLeft + gmRight + gmLJump + gmHJump)))
- TurnTimeLeft = 20000
- else
- SetInputMask(0xFFFFFFFF)
- TurnsLeft = TurnsLeft - 1
- end
-end
-
-function onPrecise()
- if GameTime > 2500 and AnimInProgress() then
- SetAnimSkip(true)
- return
- end
--- AddAmmo(leaks, amRope, 100)
--- RemoveEventFunc(CheckPastFlower)
--- DeleteGear(sniperCrate)
-end
-
--- a/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/queen.lua Mon Jul 01 22:28:42 2013 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,828 +0,0 @@
-HedgewarsScriptLoad("/Scripts/Locale.lua")
-HedgewarsScriptLoad("/Scripts/Animate.lua")
-
-
------------------------------Map--------------------------------------
-local map =
-{
- "\16\7\0\225\132\15\200\1\40\0\15\200\1\40\132\15\105\8\81\0\16\14\1\64\143\15\200\7\249\0\13\50\7\252\132\12\243\7\172\0",
- "\12\236\7\168\132\12\127\6\192\0\12\127\6\192\132\11\52\6\223\0\11\52\6\223\132\10\62\8\35\0\8\201\8\4\132\8\63\7\126\0",
- "\8\63\7\126\132\8\4\6\58\0\8\0\6\65\132\7\147\6\241\0\7\133\6\195\132\7\20\4\151\0\7\143\6\195\132\7\140\6\234\0",
- "\7\17\4\151\132\5\191\4\222\0\5\191\4\222\132\3\136\3\252\0\3\136\3\252\132\2\12\4\151\0\2\12\4\151\132\1\138\5\15\0",
- "\1\138\5\15\132\1\54\5\156\0\1\54\5\156\132\0\130\5\64\0\0\130\5\64\132\255\214\5\135\0\8\141\1\85\179\8\141\1\85\0",
- "\10\30\2\220\139\10\30\2\220\0\11\77\1\142\131\11\77\1\142\0\10\188\0\113\129\10\188\0\113\0\255\235\0\162\132\0\130\0\225\0",
- "\0\130\0\229\0\0\127\0\236\132\255\231\0\250\0\0\28\0\215\136\0\4\0\211\0\0\95\5\212\154\0\95\7\238\0\0\246\6\2\154",
- "\1\71\8\0\0\1\205\5\145\154\2\132\4\239\0\3\98\4\141\154\1\135\5\216\0\3\179\4\151\154\6\213\5\247\0\6\223\5\124\151",
- "\6\185\5\22\0\6\181\5\29\151\6\37\5\64\0\0\179\5\198\148\0\179\5\198\0\6\216\4\253\148\6\216\4\253\0\1\230\7\147\153",
- "\8\32\8\18\0\1\187\6\174\153\7\179\7\108\0\2\199\5\177\179\6\128\6\167\0\7\231\7\10\143\7\231\6\202\0\12\148\8\4\156",
- "\10\241\8\11\0\11\112\7\101\156\12\56\7\91\0\1\89\5\223\199\4\11\5\208\0\4\67\5\212\200\4\172\6\58\0\4\172\6\58\200",
- "\5\36\5\212\0\5\40\5\194\200\4\169\5\57\0\4\169\5\57\200\4\42\5\205\0\4\130\5\142\200\4\218\5\205\0\4\137\5\194\200",
- "\4\179\5\251\0\255\245\1\198\133\0\77\1\198\0\0\77\1\198\133\0\102\1\226\0\0\102\1\230\133\255\221\1\244\0\255\245\0\148\195",
- "\255\231\1\11\0\0\32\0\162\195\255\231\0\169\0\0\60\0\158\195\0\32\0\172\0\0\21\0\176\195\255\242\0\222\0\255\245\0\215\195",
- "\0\7\0\246\0\255\245\0\243\195\0\11\1\33\0\0\4\1\4\195\0\56\1\36\0\255\245\1\173\195\0\35\1\110\0\255\242\1\180\195",
- "\255\224\2\9\0\255\238\1\240\195\0\28\2\30\0\0\21\2\19\195\0\102\2\23\0\16\18\1\1\195\16\35\0\222\0\16\14\1\11\195",
- "\16\7\2\9\0\16\0\2\16\195\16\35\3\34\0\16\11\2\252\195\16\11\4\208\0\16\11\4\208\195\16\0\6\55\0\16\0\6\55\195",
- "\16\14\8\25\0",
-}
-
---------------------------------------------Constants------------------------------------
-choiceAccepted = 1
-choiceRefused = 2
-choiceAttacked = 3
-
-choiceEliminate = 1
-choiceSpare = 2
-
-leaksNum = 1
-denseNum = 2
-waterNum = 3
-buffaloNum = 4
-chiefNum = 5
-girlNum = 6
-wiseNum = 7
-
-denseScene = 1
-princessScene = 2
-waterScene = 3
-cyborgScene = 4
-
-nativeNames = {loc("Leaks A Lot"), loc("Dense Cloud"), loc("Fiery Water"),
- loc("Raging Buffalo"), loc("Righteous Beard"), loc("Fell From Grace"),
- loc("Wise Oak"), loc("Ramon"), loc("Spiky Cheese")
- }
-nativeSaveNames = {"M8DeployedDead", "M8RamonDead", "M8SpikyDead", "M8PrincessDead"}
-
-nativeUnNames = {loc("Zork"), loc("Steve"), loc("Jack"),
- loc("Lee"), loc("Elmo"), loc("Rachel"),
- loc("Muriel")}
-
-nativeHats = {"Rambo", "RobinHood", "pirate_jack", "zoo_Bunny", "IndianChief",
- "tiara", "AkuAku", "rasta", "hair_yellow"}
-
-nativePos = {{1474, 1188}, {923, 986}, {564, 1120}, {128, 1315}}
-nativesNum = 4
-nativesLeft = 4
-
-cyborgNames = {loc("Artur Detour"), loc("Led Heart"), loc("Orlando Boom!"), loc("Nilarian"),
- loc("Steel Eye"), loc("Rusty Joe"), loc("Hatless Jerry"), loc("Gas Gargler")}
-
-cyborgsDif = {2, 2, 2, 2, 2, 2, 2, 2}
-cyborgsHealth = {100, 100, 100, 100, 100, 100, 100, 100}
-cyborgPos = {1765, 1145}
-cyborgsTeamNum = {4, 3}
-cyborgsNum = 7
-cyborgsPos = {{2893, 1717}, {2958, 1701}, {3027, 1696}, {3096, 1698},
- {2584, 655}, {2047, 1534}, {115, 179}, {2162, 1916}}
-cyborgsDir = {"Left", "Left", "Left", "Left", "Left", "Left", "Right", "Left"}
-
-crateConsts = {}
-reactions = {}
-
-enemyPos = {4078, 195}
-
------------------------------Variables---------------------------------
-natives = {}
-origNatives = {}
-
-cyborgs = {}
-cyborg = nil
-
-gearDead = {}
-hedgeHidden = {}
-
-scene = 0
-enemyFled = "0"
-
-deployedLeader = "0"
-princessLeader = "0"
-
-startAnim = {}
-fleeAnim = {}
-finalAnim = {}
-leaderDeadAnim = {}
------------------------------Animations--------------------------------
-function EmitDenseClouds(dir)
- local dif
- if dir == "Left" then
- dif = 10
- else
- dif = -10
- end
- if dir == nil then
- dx, dy = GetGearVelocity(dense)
- if dx < 0 then
- dif = 10
- else
- dif = -10
- end
- end
- AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
- AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
- AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
- AnimInsertStepNext({func = AnimWait, args = {dense, 800}})
- AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
- AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
- AnimInsertStepNext({func = AnimWait, args = {dense, 800}})
- AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
-end
-
-function AnimationSetup()
- table.insert(startAnim, {func = AnimWait, args = {enemy, 3000}})
- table.insert(startAnim, {func = AnimCaption, swh = false, args = {natives[1], "The team continued their quest of finding the rest of the tribe.", 4000}})
- table.insert(startAnim, {func = AnimCaption, swh = false, args = {natives[1], "They stumbled upon a pile of weapons, they seemed to be getting closer.", 4500}})
- if scene == denseScene then
- if m5DeployedNum == denseNum then
- deployedLeader = "1"
- SetupDenseAnimDeployed()
- else
- SetupDenseAnim()
- end
- elseif scene == waterScene then
- if m5DeployedNum == waterNum then
- deployedLeader = "1"
- SetupWaterAnimDeployed()
- else
- SetupWaterAnim()
- end
- elseif scene == princessScene then
- princessLeader = "1"
- SetupPrincessAnim()
- else
- SetupCyborgAnim()
- end
-
- AddSkipFunction(startAnim, SkipAnim, {startAnim})
- AddSkipFunction(fleeAnim, SkipAnim, {fleeAnim})
- AddSkipFunction(leaderDeadAnim, SkipAnim, {leaderDeadAnim})
-end
-
-function SetupLeaderDeadAnim()
- local gear = nil
- if CheckCyborgsDead() then
- return
- end
- for i = nativesLeft, 1, -1 do
- if band(GetState(natives[i]), gstDrowning) == 0 then
- gear = natives[i]
- end
- end
- if gear == nil then
- return
- end
- table.insert(leaderDeadAnim, {func = AnimFollowGear, args = {gear}})
- table.insert(leaderDeadAnim, {func = AnimSay, args = {gear, "That traitor won't be killing us anymore!", SAY_THINK, 6000}})
-end
-
-function SetupDenseAnim()
- table.insert(startAnim, {func = AnimSay, args = {enemy, "Yo, dude! Get away from our weapons!", SAY_SHOUT, 5500}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "Dense Cloud?! What are you doing?!", SAY_SHOUT, 5500}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "What does it look like?", SAY_SHOUT, 3500}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "Are you helping the aliens?!", SAY_SHOUT, 4000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "Lolz, I love the look on your face!", SAY_SHOUT, 5000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "Did you really think that I'd changed?", SAY_SHOUT, 5500}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "But why did you betray us?!", SAY_SHOUT, 4000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "Yo, the aliens gave me plants...medicinal plants...lots of it.", SAY_SHOUT, 6500}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "You never give me plants!", SAY_SHOUT, 5500}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "Besides, why would I choose certain death?", SAY_SHOUT, 5500}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "Do you have any idea how bad an exploding arrow hurts?", SAY_SHOUT, 5500}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "Dude, it's unbearable!", SAY_SHOUT, 5500}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "You're a coward!", SAY_SHOUT, 3000}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "You endangered your whole tribe, you bastard!", SAY_SHOUT, 7000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "Yeah, well, for some dude to be happy, some other dude has to suffer.", SAY_SHOUT, 11000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "That's just the way it works, you know.", SAY_SHOUT, 6500}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "You're some piece of hypocrite junkie!", SAY_SHOUT, 6000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "Why do you always have to call me names?", SAY_SHOUT, 6000}})
- table.insert(startAnim, {func = AnimCustomFunction, args = {enemy, EmitDenseClouds, {}}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "Make fun of me when I fart...", SAY_SHOUT, 5000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "IT'S A SERIOUS MEDICAL CONDITION!", SAY_SHOUT, 5000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "You don't deserve my sacrifice!", SAY_SHOUT, 5000}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "I won't let you kill the tribe!", SAY_SHOUT, 5000}})
-
- table.insert(fleeAnim, {func = AnimSay, args = {enemy, "Dude, this is boring!", SAY_SAY, 3000}})
- table.insert(fleeAnim, {func = AnimSay, args = {enemy, "I ain't gonna sit around no more!", SAY_SAY, 5000}})
- table.insert(fleeAnim, {func = AnimTurn, args = {enemy, "Right"}})
- table.insert(fleeAnim, {func = AnimSay, args = {enemy, "Yo, escort my buttocks!", SAY_SHOUT, 3500}})
- table.insert(fleeAnim, {func = AnimSwitchHog, args = {natives[1]}})
- table.insert(fleeAnim, {func = AnimWait, args = {natives[1], 1}})
- table.insert(fleeAnim, {func = AnimDisappear, swh = false, args = {enemy, 0, 0}})
-end
-
-function SetupDenseAnimDeployed()
- table.insert(startAnim, {func = AnimCustomFunction, args = {enemy, EmitDenseClouds, {}}})
- table.insert(startAnim, {func = AnimCustomFunction, args = {enemy, CondNeedToTurn, {natives[3], enemy}}})
- table.insert(startAnim, {func = AnimCustomFunction, args = {enemy, CondNeedToTurn, {natives[2], enemy}}})
- table.insert(startAnim, {func = AnimCustomFunction, args = {enemy, CondNeedToTurn, {natives[1], enemy}}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "I'm afraid I can't let you proceed!", SAY_SHOUT, 5000}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "???", SAY_THINK, 0}})
- table.insert(startAnim, {func = AnimSay, args = {natives[2], "???", SAY_THINK, 0}})
- table.insert(startAnim, {func = AnimSay, args = {natives[3], "???", SAY_THINK, 1000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "Dude, wow, you're so cute!", SAY_SHOUT, 4000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "Did you really think I'd change?", SAY_SHOUT, 4500}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "I'm still with the aliens.", SAY_SHOUT, 4000}})
- table.insert(startAnim, {func = AnimTeleportGear, args = {enemy, unpack(enemyPos)}})
- table.insert(startAnim, {func = AnimCustomFunction, args = {enemy, CondNeedToTurn, {natives[1], enemy}}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "WHAT?!", SAY_THINK, 1000}})
- table.insert(startAnim, {func = AnimSay, args = {natives[3], "But you saved me!", SAY_THINK, 2500}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "Haha, that was just a coincidence!", SAY_SHOUT, 4000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "I was heading home, you see!", SAY_SHOUT, 3500}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "We were your home! Your family...", SAY_SHOUT, 4000}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "How could you betray us?!", SAY_SHOUT, 4000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "Yo, the aliens gave me plants...medicinal plants...lots of it.", SAY_SHOUT, 6500}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "You never give me plants!", SAY_SHOUT, 5500}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "Besides, why would I choose certain death?", SAY_SHOUT, 5500}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "Do you have any idea how bad an exploding arrow hurts?", SAY_SHOUT, 5500}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "Dude, it's unbearable!", SAY_SHOUT, 5500}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "You're a coward!", SAY_SHOUT, 3000}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "You endangered your whole tribe, you bastard!", SAY_SHOUT, 7000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "Yeah, well, for some dude to be happy, some other dude has to suffer.", SAY_SHOUT, 11000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "That's just the way it works, you know.", SAY_SHOUT, 6500}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "You're some piece of hypocrite junkie!", SAY_SHOUT, 6000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "Why do you always have to call me names?", SAY_SHOUT, 6000}})
- table.insert(startAnim, {func = AnimCustomFunction, args = {enemy, EmitDenseClouds, {}}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "Make fun of me when I fart...", SAY_SHOUT, 5000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "IT'S A SERIOUS MEDICAL CONDITION!", SAY_SHOUT, 5000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "You don't deserve my sacrifice!", SAY_SHOUT, 5000}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "I won't let you kill the tribe!", SAY_SHOUT, 5000}})
-
- table.insert(fleeAnim, {func = AnimSay, args = {enemy, "Dude, this is boring!", SAY_SAY, 3000}})
- table.insert(fleeAnim, {func = AnimSay, args = {enemy, "I ain't gonna sit around no more!", SAY_SAY, 5000}})
- table.insert(fleeAnim, {func = AnimTurn, args = {enemy, "Right"}})
- table.insert(fleeAnim, {func = AnimSay, args = {enemy, "Yo, escort my buttocks!", SAY_SHOUT, 3500}})
- table.insert(fleeAnim, {func = AnimSwitchHog, args = {natives[1]}})
- table.insert(fleeAnim, {func = AnimWait, args = {natives[1], 1}})
- table.insert(fleeAnim, {func = AnimDisappear, swh = false, args = {enemy, 0, 0}})
-end
-
-function SetupWaterAnim()
- table.insert(startAnim, {func = AnimSay, args = {enemy, "Stay there, comrades!", SAY_SHOUT, 2500}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "Come closer and die...burp!", SAY_SHOUT, 4000}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "Fiery Water?! Are you drunk again?", SAY_SHOUT, 5000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "Drunk with power, perhappss!", SAY_SHOUT, 4000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "The power of love! No, wait, the power of the aliens!", SAY_SHOUT, 7500}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "We trusted you, you fool!", SAY_SHOUT, 4000}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "Why do you keep betraying us?", SAY_SHOUT, 4000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "Why, why, why, why!", SAY_SHOUT, 4000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "I grew sick of the oppression! I brock free!", SAY_SHOUT, 6500}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "What oppression?! You were the most unoppressed member of the tribe!", SAY_SHOUT, 10000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "The opression of the elders, of course!", SAY_SHOUT, 6500}})
- if m5DeployedNum == leaksNum then
- table.insert(startAnim, {func = AnimSay, args = {enemy, "You should know this more than anyone, Leaks!", SAY_SHOUT, 7000}})
- elseif m5LeaksDead == 1 then
- table.insert(startAnim, {func = AnimSay, args = {enemy, "Just look at Leaks, may he rest in peace!", SAY_SHOUT, 6500}})
- end
- table.insert(startAnim, {func = AnimSay, args = {enemy, "We, the youth, have to constantly prove our value...", SAY_SHOUT, 7000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "We work and work until we sweat blood...", SAY_SHOUT, 5000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "We risk our lives going through challenges...", SAY_SHOUT, 6000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "All this to please our beloved 'elders'...hick...", SAY_SHOUT, 6000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "And what do they do in the meantime? NOTHING!", SAY_SHOUT, 6000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "All they do is sit around and judge us!", SAY_SHOUT, 6000}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "You have never worked a bit in your life!", SAY_SHOUT, 6000}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "All *you* do is take long walks when everyone else works.", SAY_SHOUT, 9000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "Anyway, the aliens accept me for who I am.", SAY_SHOUT, 7000}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "We won't accept you destroying our village!", SAY_SHOUT, 7000}})
-
- table.insert(fleeAnim, {func = AnimSay, args = {enemy, "Argh, the borrdommm!", SAY_SAY, 3000}})
- table.insert(fleeAnim, {func = AnimSay, args = {enemy, "I have more important things to do!", SAY_SAY, 5000}})
- table.insert(fleeAnim, {func = AnimTurn, args = {enemy, "Right"}})
- table.insert(fleeAnim, {func = AnimSay, args = {enemy, "Comrades! Sail me away!", SAY_SHOUT, 3500}})
- table.insert(fleeAnim, {func = AnimSwitchHog, args = {natives[1]}})
- table.insert(fleeAnim, {func = AnimWait, args = {natives[1], 1}})
- table.insert(fleeAnim, {func = AnimDisappear, swh = false, args = {enemy, 0, 0}})
-end
-
-function SetupWaterAnimDeployed()
- table.insert(startAnim, {func = AnimCustomFunction, args = {enemy, CondNeedToTurn, {natives[3], enemy}}})
- table.insert(startAnim, {func = AnimCustomFunction, args = {enemy, CondNeedToTurn, {natives[2], enemy}}})
- table.insert(startAnim, {func = AnimCustomFunction, args = {enemy, CondNeedToTurn, {natives[1], enemy}}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "Stop, comrades!", SAY_SHOUT, 2500}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "I cannot let you go any farther...burp!", SAY_SHOUT, 5500}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "Fiery Water?! Are you drunk again?", SAY_SHOUT, 5000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "Drunk with power, perhappss!", SAY_SHOUT, 4000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "The power of love! No, wait, the power of the aliens!", SAY_SHOUT, 7500}})
- table.insert(startAnim, {func = AnimTeleportGear, args = {enemy, unpack(enemyPos)}})
- table.insert(startAnim, {func = AnimCustomFunction, args = {enemy, CondNeedToTurn, {natives[3], enemy}}})
- table.insert(startAnim, {func = AnimCustomFunction, args = {enemy, CondNeedToTurn, {natives[2], enemy}}})
- table.insert(startAnim, {func = AnimCustomFunction, args = {enemy, CondNeedToTurn, {natives[1], enemy}}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "We trusted you, you fool!", SAY_SHOUT, 4000}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "Why do you keep betraying us?", SAY_SHOUT, 4000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "Why, why, why, why!", SAY_SHOUT, 4000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "I grew sick of the oppression! I brock free!", SAY_SHOUT, 6500}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "What oppression?! You were the most unoppressed member of the tribe!", SAY_SHOUT, 10000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "The opression of the elders, of course!", SAY_SHOUT, 6500}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "Just look at Leaks, may he rest in peace!", SAY_SHOUT, 6500}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "We, the youth, have to constantly prove our value...", SAY_SHOUT, 7000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "We work and work until we sweat blood...", SAY_SHOUT, 5000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "We risk our lives going through challenges...", SAY_SHOUT, 6000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "All this to please our beloved 'elders'...hick...", SAY_SHOUT, 6000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "And what do they do in the meantime? NOTHING!", SAY_SHOUT, 6000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "All they do is sit around and judge us!", SAY_SHOUT, 6000}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "You have never worked a bit in your life!", SAY_SHOUT, 6000}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "All *you* do is take long walks when everyone else works.", SAY_SHOUT, 9000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "Anyway, the aliens accept me for who I am.", SAY_SHOUT, 7000}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "We won't accept you destroying our village!", SAY_SHOUT, 7000}})
-
- table.insert(fleeAnim, {func = AnimSay, args = {enemy, "Argh, the borrdommm!", SAY_SAY, 3000}})
- table.insert(fleeAnim, {func = AnimSay, args = {enemy, "I have more important things to do!", SAY_SAY, 5000}})
- table.insert(fleeAnim, {func = AnimTurn, args = {enemy, "Right"}})
- table.insert(fleeAnim, {func = AnimSay, args = {enemy, "Comrades! Sail me away!", SAY_SHOUT, 3500}})
- table.insert(fleeAnim, {func = AnimSwitchHog, args = {natives[1]}})
- table.insert(fleeAnim, {func = AnimWait, args = {natives[1], 1}})
- table.insert(fleeAnim, {func = AnimDisappear, swh = false, args = {enemy, 0, 0}})
-end
-
-function SetupPrincessAnim()
- table.insert(startAnim, {func = AnimCustomFunction, args = {enemy, CondNeedToTurn, {natives[3], enemy}}})
- table.insert(startAnim, {func = AnimCustomFunction, args = {enemy, CondNeedToTurn, {natives[2], enemy}}})
- table.insert(startAnim, {func = AnimCustomFunction, args = {enemy, CondNeedToTurn, {natives[1], enemy}}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "Oh, my! I forgot something!", SAY_SHOUT, 4000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "We need to go back!", SAY_SHOUT, 3000}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "What could you possibly forget in that cage?", SAY_SHOUT, 7000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "I don't like your tone! You're hurting me!", SAY_SHOUT, 4000}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "I'm terribly sorry!", SAY_SHOUT, 4000}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "What is it that you forgot?", SAY_SHOUT, 4000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "Uhmm, it's...uhm...my ring!", SAY_SHOUT, 4000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "It's precious to me!", SAY_SHOUT, 3000}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "We don't have time for that now!", SAY_SHOUT, 5000}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "We have to find our folk!", SAY_SHOUT, 4000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "But I want my sandals!", SAY_SHOUT, 3000}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "Sandals?! I thought you left your ring!", SAY_SHOUT, 6000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "All right, you got me...", SAY_SHOUT, 3000}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "Got you? You're acting weird...", SAY_SHOUT, 4000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "You just can't let it go, can you!", SAY_SHOUT, 5000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "All right, I'll admit it!", SAY_SHOUT, 4000}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "Admit what?", SAY_SHOUT, 2000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "You give me no choice!", SAY_SHOUT, 4000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "I can't let you go further because...", SAY_SHOUT, 6000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "I'm the spy! I've been giving you out!", SAY_SHOUT, 6000}})
- table.insert(startAnim, {func = AnimTeleportGear, args = {enemy, unpack(enemyPos)}})
- table.insert(startAnim, {func = AnimCustomFunction, args = {enemy, CondNeedToTurn, {natives[3], enemy}}})
- table.insert(startAnim, {func = AnimCustomFunction, args = {enemy, CondNeedToTurn, {natives[2], enemy}}})
- table.insert(startAnim, {func = AnimCustomFunction, args = {enemy, CondNeedToTurn, {natives[1], enemy}}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "But...they kidnapped you!", SAY_SHOUT, 4000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "Oh, that. We were just having fun!", SAY_SHOUT, 5000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "It's an ancient ritual of theirs.", SAY_SHOUT, 5000}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "Why did you do this?", SAY_SHOUT, 4000}})
- if m5ChiefDead == 1 then
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "Why did you kill your father?", SAY_SHOUT, 5000}})
- end
- table.insert(startAnim, {func = AnimSay, args = {enemy, "Do you have any idea what it's like in the village for a woman?", SAY_SHOUT, 10000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "How would you like being discriminated against?", SAY_SHOUT, 7000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "Not being able to fight, hunt...", SAY_SHOUT, 5000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "Gathering fruits all day long...", SAY_SHOUT, 5000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "Doing stuff a monkey could do...", SAY_SHOUT, 5000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "Always being considered weak and fragile...", SAY_SHOUT, 6000}})
- if m5DeployedNum == girlNum then
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "In case you haven't noticed, I'm a woman, too!", SAY_SHOUT, 8000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "Yes, but you're...different!", SAY_SHOUT, 6000}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "Of course I am...", SAY_SHOUT, 3000}})
- end
- table.insert(startAnim, {func = AnimSay, args = {enemy, "The aliens respect me, even worship me!", SAY_SHOUT, 6000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "I'm living a dream!", SAY_SHOUT, 3000}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "Well, you're about to wake up!", SAY_SHOUT, 5000}})
-
- table.insert(fleeAnim, {func = AnimSay, args = {enemy, "Hmm...it's going slower than expected.", SAY_SAY, 5000}})
- table.insert(fleeAnim, {func = AnimSay, args = {enemy, "I am going to leave the kids play by themselves.", SAY_SAY, 6000}})
- table.insert(fleeAnim, {func = AnimTurn, args = {enemy, "Right"}})
- table.insert(fleeAnim, {func = AnimSay, args = {enemy, "Alien! I wish to be moved!", SAY_SHOUT, 4000}})
- table.insert(fleeAnim, {func = AnimSwitchHog, args = {natives[1]}})
- table.insert(fleeAnim, {func = AnimWait, args = {natives[1], 1}})
- table.insert(fleeAnim, {func = AnimDisappear, swh = false, args = {enemy, 0, 0}})
-end
-
-function SetupCyborgAnim()
- table.insert(startAnim, {func = AnimSay, args = {enemy, "Stop right there, puny worms!", SAY_SHOUT, 4000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "Stay away from our weapons!", SAY_SHOUT, 4000}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "We come in peace! Just let our friends go!", SAY_SHOUT, 5500}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "I'm afraid we cannot afford that...", SAY_SHOUT, 4500}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "You see, hedgehog spikes are very very valuable.", SAY_SHOUT, 6500}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "Very valuable, haha!", SAY_SHOUT, 3500}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "Don't you dare harm our tribe!", SAY_SHOUT, 5000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "It's a shame, really!", SAY_SHOUT, 4000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "I regret to end your little odyssey.", SAY_SHOUT, 5000}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "It was fun to watch...", SAY_SHOUT, 3500}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "The way you handled your little internal conflicts...", SAY_SHOUT, 6500}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "Did you really think that we needed the help of one of you?", SAY_SHOUT, 7500}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "You should have known that we don't rely on meatbags!", SAY_SHOUT, 7500}})
- table.insert(startAnim, {func = AnimSay, args = {enemy, "It was fun to watch though...", SAY_SHOUT, 3500}})
- if m5Choice == choiceEliminate then
- table.insert(startAnim, {func = AnimSay, args = {enemy, "Heck, you even executed one of your own!", SAY_SHOUT, 6000}})
- end
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "It was all a trick?!", SAY_SHOUT, 3000}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "Some sick game of yours?!", SAY_SHOUT, 4000}})
- table.insert(startAnim, {func = AnimSay, args = {natives[1], "We won't let you hurt any more of us!", SAY_SHOUT, 6000}})
-
- table.insert(fleeAnim, {func = AnimSay, args = {enemy, "Entered boredom phase! Discrepancies detected...", SAY_SAY, 5000}})
- table.insert(fleeAnim, {func = AnimSay, args = {enemy, "Initiate escape wish!", SAY_SAY, 6000}})
- table.insert(fleeAnim, {func = AnimTurn, args = {enemy, "Right"}})
- table.insert(fleeAnim, {func = AnimSay, args = {enemy, "Running displacement algorithm...", SAY_SHOUT, 4000}})
- table.insert(fleeAnim, {func = AnimSwitchHog, args = {natives[1]}})
- table.insert(fleeAnim, {func = AnimWait, args = {natives[1], 1}})
- table.insert(fleeAnim, {func = AnimDisappear, swh = false, args = {enemy, 0, 0}})
-end
-
-function SetupFinalAnim()
- local found = 0
- local gears = {}
- for i = nativesLeft, 1, -1 do
- if band(GetState(natives[i]), gstDrowning) == 0 then
- found = found + 1
- gears[found] = natives[i]
- end
- end
- if found == 0 then
- return
- else
- for i = 1, found do
- table.insert(finalAnim, {func = AnimCustomFunction, args = {gears[1], CondNeedToTurn, {cyborg, gears[i]}}})
- end
- table.insert(finalAnim, {func = AnimSay, args = {cyborg, "Nice work, meatbags!", SAY_SAY, 3000}})
- table.insert(finalAnim, {func = AnimSay, args = {cyborg, "You're on your way to freeing your tribe!", SAY_SAY, 5500}})
- table.insert(finalAnim, {func = AnimSay, args = {gears[1], "Do you know where they are?", SAY_SAY, 4000}})
- table.insert(finalAnim, {func = AnimSay, args = {gears[found], "We need to hurry!", SAY_SAY, 3000}})
- table.insert(finalAnim, {func = AnimSay, args = {cyborg, "Haha! Come!", SAY_SAY, 2000}})
- table.insert(finalAnim, {func = AnimJump, args = {cyborg, "high"}})
- table.insert(finalAnim, {func = AnimDisappear, args = {cyborg, GetGearPosition(cyborg)}})
- for i = 1, found do
- table.insert(finalAnim, {func = HideHedge, swh = false, args = {gears[i]}})
- end
- table.insert(finalAnim, {func = SetState, swh = false, args = {cyborg, gstInvisible}})
- end
-end
-
-
---------------------------Anim skip functions--------------------------
-function AfterStartAnim()
- SetGearMessage(natives[1], 0)
- ShowMission("Long Live The Queen", "Closing in", "Defeat the enemy!|The leader seems scared, he will probably flee.", 1, 0)
- SetHealth(SpawnHealthCrate(2207, 44), 25)
- SetHealth(SpawnHealthCrate(519, 1519), 25)
- SetHealth(SpawnHealthCrate(826, 895), 25)
- SpawnUtilityCrate(701, 1046, amGirder, 3)
- TurnTimeLeft = TurnTime
-end
-
-function SkipAnim(anim)
- if anim == startAnim then
- SetGearPosition(enemy, unpack(enemyPos))
- end
- if GetHogTeamName(CurrentHedgehog) ~= loc("Natives") then
- TurnTimeLeft = 0
- end
- AnimWait(enemy, 1)
-end
-
-function AfterFleeAnim()
- SetHealth(SpawnHealthCrate(130, 455), 25)
- SetHealth(SpawnHealthCrate(2087, 50), 25)
- SetHealth(SpawnHealthCrate(2143, 54), 25)
- SetHealth(SpawnHealthCrate(70, 1308), 25)
- SetGearMessage(CurrentHedgehog, 0)
- HideHedge(enemy)
- ShowMission("Long Live The Queen", "Coward", "The leader escaped. Defeat the rest of the aliens!", 1, 0)
- TurnTimeLeft = TurnTime
-end
-
-function AfterLeaderDeadAnim()
- SetHealth(SpawnHealthCrate(130, 455), 25)
- SetHealth(SpawnHealthCrate(2087, 50), 25)
- SetHealth(SpawnHealthCrate(2143, 54), 25)
- SetHealth(SpawnHealthCrate(70, 1308), 25)
- ShowMission("Long Live The Queen", "Bullseye", "Good Job! Defeat the rest of the aliens!", 1, 0)
- TurnTimeLeft = 0
-end
------------------------------Events------------------------------------
-function CheckTurnsOver()
- return TotalRounds > 6
-end
-
-function DoTurnsOver()
- SetGearMessage(CurrentHedgehog, 0)
- enemyFled = "1"
- AddAnim(fleeAnim)
- AddFunction({func = AfterFleeAnim, args = {}})
- RemoveEventFunc(CheckGearDead, {enemy})
-end
-
-function CheckNativesDead()
- return nativesLeft == 0
-end
-
-function DoNativesDead()
- RemoveEventFunc(CheckTurnsOver)
- RemoveEventFunc(CheckGearDead)
- RemoveEventFunc(CheckCyborgsDead)
- AddCaption("...and the cyborgs took over the island.")
- TurnTimeLeft = 0
-end
-
-function CheckCyborgsDead()
- return (cyborgsLeft == 0 and (gearDead[enemy] == true or enemyFled == "1"))
-end
-
-function KillEnemy()
- if enemyFled == "1" then
- ParseCommand("teamgone " .. loc("Leaderbot"))
- end
- ParseCommand("teamgone " .. loc("011101001"))
- TurnTimeLeft = 0
-end
-
-function DoCyborgsDead()
- SaveCampaignVariables()
- RestoreHedge(cyborg)
- PlaceGirder(3292, 922, 4)
- SetGearPosition(cyborg, 3290, 902)
- SetupFinalAnim()
- AddAnim(finalAnim)
- AddFunction({func = KillEnemy, args = {}})
-end
-
-function DoLeaderDead()
- leaderDead = true
- SetGearMessage(CurrentHedgehog, 0)
- SetupLeaderDeadAnim()
- AddAnim(leaderDeadAnim)
- AddFunction({func = AfterLeaderDeadAnim, args = {}})
- RemoveEventFunc(CheckTurnsOver)
-end
-
-function CheckGearsDead(gearList)
- for i = 1, # gearList do
- if gearDead[gearList[i]] ~= true then
- return false
- end
- end
- return true
-end
-
-function CheckGearDead(gear)
- return gearDead[gear]
-end
-
------------------------------Misc--------------------------------------
-function HideHedge(hedge)
- if hedgeHidden[hedge] ~= true then
- HideHog(hedge)
- hedgeHidden[hedge] = true
- end
-end
-
-function RestoreHedge(hedge)
- if hedgeHidden[hedge] == true then
- RestoreHog(hedge)
- hedgeHidden[hedge] = false
- end
-end
-
-function GetVariables()
- progress = tonumber(GetCampaignVar("Progress"))
- m5DeployedNum = tonumber(GetCampaignVar("M5DeployedNum"))
- m2Choice = tonumber(GetCampaignVar("M2Choice"))
- m5Choice = tonumber(GetCampaignVar("M5Choice"))
- m2DenseDead = tonumber(GetCampaignVar("M2DenseDead"))
- m4DenseDead = tonumber(GetCampaignVar("M4DenseDead"))
- m5DenseDead = tonumber(GetCampaignVar("M5DenseDead"))
- m4LeaksDead = tonumber(GetCampaignVar("M4LeaksDead"))
- m5LeaksDead = tonumber(GetCampaignVar("M5LeaksDead"))
- m4ChiefDead = tonumber(GetCampaignVar("M4ChiefDead"))
- m5ChiefDead = tonumber(GetCampaignVar("M5ChiefDead"))
- m4WaterDead = tonumber(GetCampaignVar("M4WaterDead"))
- m5WaterDead = tonumber(GetCampaignVar("M5WaterDead"))
- m4BuffaloDead = tonumber(GetCampaignVar("M4BuffaloDead"))
- m5BuffaloDead = tonumber(GetCampaignVar("M5BuffaloDead"))
- m5WiseDead = tonumber(GetCampaignVar("M5WiseDead"))
- m5GirlDead = tonumber(GetCampaignVar("M5GirlDead"))
-end
-
-function SaveCampaignVariables()
- for i = 1, 4 do
- if gearDead[origNatives[i]] ~= true then
- SaveCampaignVar(nativeSaveNames[i], "0")
- else
- SaveCampaignVar(nativeSaveNames[i], "1")
- end
- end
-
- SaveCampaignVar("M8DeployedLeader", deployedLeader)
- SaveCampaignVar("M8PrincessLeader", princessLeader)
- SaveCampaignVar("M8EnemyFled", enemyFled)
- SaveCampaignVar("M8Scene", "" .. scene)
- if progress and progress<8 then
- SaveCampaignVar("Progress", "8")
- end
-end
-
-function SetupPlace()
- HideHedge(cyborg)
- SetHogHat(natives[1], nativeHats[m5DeployedNum])
- SetHogName(natives[1], nativeNames[m5DeployedNum])
-
- if m5DeployedNum == denseNum then
- dense = natives[1]
- else
- dense = enemy
- end
-
- if m2Choice == choiceAccepted and m5Choice ~= choiceEliminate then
- scene = denseScene
- SetHogHat(enemy, nativeHats[denseNum])
- SetHogName(enemy, nativeNames[denseNum])
- dense = enemy
- elseif m2Choice == choiceAccepted then
- scene = cyborgScene
- SetHogHat(enemy, "cyborg2")
- SetHogName(enemy, loc("Nancy Screw"))
- elseif m5Choice == choiceEliminate then
- scene = princessScene
- SetHogHat(enemy, "tiara")
- SetHogName(enemy, loc("Fell From Heaven"))
- else
- scene = waterScene
- SetHogHat(enemy, nativeHats[waterNum])
- SetHogName(enemy, nativeNames[waterNum])
- end
- for i = 1, 4 do
- if GetHogName(natives[i]) == GetHogName(enemy) then
- AnimSetGearPosition(enemy, GetGearPosition(natives[i]))
- DeleteGear(natives[i])
- DeleteGear(cyborgs[cyborgsLeft])
- end
- end
-
- SpawnAmmoCrate(34, 395, amBee, 2)
- SpawnAmmoCrate(33, 374, amRCPlane, 1)
- SpawnAmmoCrate(74, 393, amAirAttack, 3)
- SpawnAmmoCrate(1313, 1481, amBazooka, 8)
- SpawnAmmoCrate(80, 360, amSniperRifle, 4)
- SpawnAmmoCrate(1037, 1494, amShotgun, 7)
- SpawnAmmoCrate(1037, 1472, amMolotov, 3)
- SpawnAmmoCrate(1146, 1503, amMortar, 8)
-
- SpawnUtilityCrate(1147, 1431, amPortalGun, 2)
- SpawnUtilityCrate(1219, 1542, amRope, 5)
- SpawnUtilityCrate(1259, 1501, amJetpack, 2)
-end
-
-function SetupEvents()
- AddNewEvent(CheckNativesDead, {}, DoNativesDead, {}, 0)
- AddNewEvent(CheckGearDead, {enemy}, DoLeaderDead, {}, 0)
- AddNewEvent(CheckTurnsOver, {}, DoTurnsOver, {}, 0)
- AddNewEvent(CheckCyborgsDead, {}, DoCyborgsDead, {}, 0)
-end
-
-function SetupAmmo()
- AddAmmo(natives[1], amPickHammer, 2)
- AddAmmo(natives[1], amBazooka, 0)
- AddAmmo(natives[1], amGrenade, 0)
- AddAmmo(natives[1], amShotgun, 0)
- AddAmmo(natives[1], amAirStrike, 0)
- AddAmmo(natives[1], amMolotov, 0)
-end
-
-function AddHogs()
- AddTeam(loc("Natives"), 29439, "Bone", "Island", "HillBilly", "cm_birdy")
- for i = 7, 9 do
- natives[i-6] = AddHog(nativeNames[i], 0, 100, nativeHats[i])
- origNatives[i-6] = natives[i-6]
- end
- natives[4] = AddHog(loc("Fell From Heaven"), 0, 133, "tiara")
- origNatives[4] = natives[4]
- nativesLeft = nativesNum
-
- AddTeam(loc("Beep Loopers"), 14483456, "ring", "UFO", "Robot", "cm_star")
- for i = 1, cyborgsTeamNum[1] do
- cyborgs[i] = AddHog(cyborgNames[i], cyborgsDif[i], cyborgsHealth[i], "cyborg2")
- end
-
- AddTeam(loc("Corporationals"), 14483456, "ring", "UFO", "Robot", "cm_star")
- for i = cyborgsTeamNum[1] + 1, cyborgsNum do
- cyborgs[i] = AddHog(cyborgNames[i], cyborgsDif[i], cyborgsHealth[i], "cyborg2")
- end
- cyborgsLeft = cyborgsTeamNum[1] + cyborgsTeamNum[2]
-
- AddTeam(loc("Leaderbot"), 14483456, "ring", "UFO", "Robot", "cm_star")
- enemy = AddHog(loc("Name"), 2, 200, "cyborg1")
-
- AddTeam(loc("011101001"), 14483456, "ring", "UFO", "Robot", "cm_star")
- cyborg = AddHog(loc("Unit 334a$7%;.*"), 0, 200, "cyborg1")
-
- SetGearPosition(cyborg, 0, 0)
-
- for i = 1, nativesNum do
- AnimSetGearPosition(natives[i], unpack(nativePos[i]))
- end
-
- AnimSetGearPosition(enemy, unpack(enemyPos))
- AnimTurn(enemy, "Left")
-
- for i = 1, cyborgsNum do
- AnimSetGearPosition(cyborgs[i], unpack(cyborgsPos[i]))
- AnimTurn(cyborgs[i], cyborgsDir[i])
- end
-end
-
-function CondNeedToTurn(hog1, hog2)
- xl, xd = GetX(hog1), GetX(hog2)
- if xl > xd then
- AnimInsertStepNext({func = AnimTurn, args = {hog1, "Left"}})
- AnimInsertStepNext({func = AnimTurn, args = {hog2, "Right"}})
- elseif xl < xd then
- AnimInsertStepNext({func = AnimTurn, args = {hog2, "Left"}})
- AnimInsertStepNext({func = AnimTurn, args = {hog1, "Right"}})
- end
-end
-
------------------------------Main Functions----------------------------
-
-function onGameInit()
- Seed = 0
- GameFlags = gfDisableGirders + gfDisableLandObjects
- TurnTime = 60000
- CaseFreq = 0
- MinesNum = 0
- MinesTime = 3000
- Explosives = 0
- Delay = 10
- MapGen = 2
- Theme = "Hell"
- SuddenDeathTurns = 20
-
- for i = 1, #map do
- ParseCommand('draw ' .. map[i])
- end
-
- GetVariables()
- AnimInit()
- AddHogs()
-end
-
-function onGameStart()
- SetupAmmo()
- SetupPlace()
- AnimationSetup()
- SetupEvents()
- AddAnim(startAnim)
- AddFunction({func = AfterStartAnim, args = {}})
-end
-
-function onGameTick()
- AnimUnWait()
- if ShowAnimation() == false then
- return
- end
- ExecuteAfterAnimations()
- CheckEvents()
-end
-
-function onGearDelete(gear)
- local toRemove = nil
- gearDead[gear] = true
- if GetGearType(gear) == gtHedgehog then
- if GetHogTeamName(gear) == loc("Beep Loopers") or GetHogTeamName(gear) == loc("Corporationals") then
- cyborgsLeft = cyborgsLeft - 1
- elseif GetHogTeamName(gear) == loc("Natives") then
- for i = 1, nativesLeft do
- if natives[i] == gear then
- toRemove = i
- end
- end
- table.remove(natives, toRemove)
- nativesLeft = nativesLeft - 1
- end
- end
-end
-
-function onAmmoStoreInit()
- SetAmmo(amBaseballBat, 9, 0, 0, 0)
- SetAmmo(amFirePunch, 9, 0, 0, 0)
- SetAmmo(amDEagle, 9, 0, 0, 0)
- SetAmmo(amSkip, 9, 0, 0, 0)
- SetAmmo(amSwitch, 9, 0, 0, 0)
- SetAmmo(amBazooka, 9, 0, 0, 0)
- SetAmmo(amGrenade, 9, 0, 0, 0)
- SetAmmo(amAirStrike, 1, 0, 0, 0)
- SetAmmo(amMolotov, 5, 0, 0, 0)
- SetAmmo(amShotgun, 9, 0, 0, 0)
-end
-
-function onNewTurn()
- if AnimInProgress() then
- TurnTimeLeft = -1
- return
- end
- if GetHogTeamName(CurrentHedgehog) == loc("011101001") then
- TurnTimeLeft = 0
- end
-end
-
-function onPrecise()
- if GameTime > 2500 and AnimInProgress() then
- SetAnimSkip(true)
--- else
--- DeleteGear(cyborgs[1])
--- table.remove(cyborgs, 1)
--- if cyborgsLeft == 0 then
--- DeleteGear(enemy)
--- end
- end
-end
Binary file share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/shadow.hwp has changed
--- a/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/shadow.lua Mon Jul 01 22:28:42 2013 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,969 +0,0 @@
-HedgewarsScriptLoad("/Scripts/Locale.lua")
-HedgewarsScriptLoad("/Scripts/Animate.lua")
-
------------------------------Constants---------------------------------
-startStage = 0
-spyStage = 1
-wave1Stage = 2
-wave2Stage = 3
-cyborgStage = 4
-ramonStage = 5
-aloneStage = 6
-duoStage = 7
-interSpyStage = 8
-interWeakStage = 9
-acceptedReturnStage = 10
-refusedReturnStage = 11
-attackedReturnStage = 12
-loseStage = 13
-
-ourTeam = 0
-weakTeam = 1
-strongTeam = 2
-cyborgTeam = 3
-
-leaksNr = 0
-denseNr = 1
-
-choiceAccept = 1
-choiceRefuse = 2
-choiceAttack = 3
-
-HogNames = {loc("Brainiac"), loc("Corpsemonger"), loc("Femur Lover"), loc("Glark"), loc("Bonely"), loc("Rot Molester"), loc("Bloodrocutor"), loc("Muscle Dissolver"), loc("Bloodsucker")}
-
----POSITIONS---
-
-cannibalPos = {{3108, 1127},
- {2559, 1080}, {3598, 1270}, {3293, 1177}, {2623, 1336},
- {3418, 1336}, {3447, 1335}, {3481, 1340}, {3507, 1324}}
-densePos = {2776, 1177}
-leaksPos = {2941, 1172}
-cyborgPos = {1113, 1818}
-
----Animations
-
-startDialogue = {}
-weaklingsAnim = {}
-stronglingsAnim = {}
-acceptedAnim = {}
-acceptedSurvivedFinalAnim = {}
-acceptedDiedFinalAnim = {}
-refusedAnim = {}
-refusedFinalAnim = {}
-attackedAnim = {}
-attackedFinalAnim = {}
-
------------------------------Variables---------------------------------
-lastHogTeam = ourTeam
-lastOurHog = leaksNr
-lastEnemyHog = 0
-stage = 0
-choice = 0
-
-brainiacDead = false
-cyborgHidden = false
-leaksHidden = false
-denseHidden = false
-cyborgAttacked = false
-retryReturn = false
-shotgunTaken = false
-grenadeTaken = false
-spikyDead = false
-ramonDead = false
-denseDead = false
-leaksDead = false
-ramonHidden = false
-spikyHidden = false
-grenadeUsed = false
-shotgunUsed = false
-
-
-hogNr = {}
-cannibalDead = {}
-isHidden = {}
-
-
---------------------------Anim skip functions--------------------------
-function AfterRefusedAnim()
- SpawnUtilityCrate(2045, 1575, amSwitch)
- SpawnUtilityCrate(2365, 1495, amShotgun)
- SpawnUtilityCrate(2495, 1519, amGrenade)
- SpawnUtilityCrate(2620, 1524, amRope)
- ShowMission(loc("The Shadow Falls"), loc("The Showdown"), loc("Save Leaks A Lot!|Hint: The Switch utility might be of help to you."), 1, 6000)
- RemoveEventFunc(CheckDenseDead)
- AddEvent(CheckStronglingsDead, {}, DoStronglingsDeadRefused, {}, 0)
- AddAmmo(cannibals[6], amGrenade, 1)
- AddAmmo(cannibals[7], amGrenade, 1)
- AddAmmo(cannibals[8], amGrenade, 1)
- AddAmmo(cannibals[9], amGrenade, 1)
- stage = ramonStage
- SwitchHog(cannibals[9])
- FollowGear(ramon)
- TurnTimeLeft = 0
- SetGearMessage(ramon, 0)
- SetGearMessage(leaks, 0)
- AnimWait(ramon, 1)
- AddFunction({func = HideHog, args = {cyborg}})
-end
-
-function SkipRefusedAnim()
- RefusedStart()
- AnimSetGearPosition(dense, 2645, 1146)
- AnimSetGearPosition(ramon, 2218, 1675)
- AnimSetGearPosition(spiky, 2400, 1675)
-end
-
-function AfterStartDialogue()
- stage = spyStage
- ShowMission(loc("The Shadow Falls"), loc("Play with me!"), loc("Defend yourself!|Hint: You can get tips on using weapons by moving your mouse over them in the weapon selection menu"), 1, 6000)
- TurnTimeLeft = TurnTime
-end
-
-
-function StartSkipFunc()
- SetState(cannibals[1], 0)
- AnimTurn(leaks, "Right")
- AnimSwitchHog(leaks)
- SetInputMask(0xFFFFFFFF)
-end
-
-function AfterWeaklingsAnim()
- AddAmmo(cannibals[2], amShotgun, 1)
- AddAmmo(cannibals[2], amGrenade, 1)
- AddAmmo(cannibals[3], amShotgun, 1)
- AddAmmo(cannibals[3], amGrenade, 1)
- AddAmmo(cannibals[4], amShotgun, 1)
- AddAmmo(cannibals[4], amGrenade, 1)
- AddAmmo(cannibals[5], amShotgun, 1)
- AddAmmo(cannibals[5], amGrenade, 1)
- AddAmmo(leaks, amSkip, 4)
- AddAmmo(dense, amSkip, 4)
- AddEvent(CheckWeaklingsKilled, {}, DoWeaklingsKilled, {}, 0)
- SetHealth(SpawnHealthCrate(2757, 1030), 50)
- SetHealth(SpawnHealthCrate(2899, 1009), 50)
- stage = wave1Stage
- SwitchHog(dense)
- SetGearMessage(dense, 0)
- SetGearMessage(leaks, 0)
- TurnTimeLeft = TurnTime
- ShowMission(loc("The Shadow Falls"), loc("Why do you not like me?"), loc("Obliterate them!|Hint: You might want to take cover..."), 1, 6000)
-end
-
-function SkipWeaklingsAnim()
- for i = 2, 5 do
- if isHidden[cannibals[i]] == true then
- RestoreHog(cannibals[i])
- isHidden[cannibals[i]] = false
- end
- AnimSetGearPosition(cannibals[i], unpack(cannibalPos[i]))
- SetState(cannibals[i], 0)
- end
- SetInputMask(0xFFFFFFFF)
-end
-
-function AfterStronglingsAnim()
- stage = cyborgStage
- ShowMission(loc("The Shadow Falls"), loc("The Dilemma"), loc("Choose your side! If you want to join the strange man, walk up to him.|Otherwise, walk away from him. If you decide to att...nevermind..."), 1, 8000)
- AddEvent(CheckChoice, {}, DoChoice, {}, 0)
- AddEvent(CheckRefuse, {}, DoRefuse, {}, 0)
- AddEvent(CheckAccept, {}, DoAccept, {}, 0)
- AddEvent(CheckConfront, {}, DoConfront, {}, 0)
- AddAmmo(dense, amSwitch, 0)
- AddAmmo(dense, amSkip, 0)
- AddAmmo(leaks, amSwitch, 0)
- AddAmmo(leaks, amSkip, 0)
- SetHealth(SpawnHealthCrate(2557, 1030), 50)
- SetHealth(SpawnHealthCrate(3599, 1009), 50)
- TurnTimeLeft = 0
-end
-
-function SkipStronglingsAnim()
- for i = 6, 9 do
- if isHidden[cannibals[i]] == true then
- RestoreHog(cannibals[i])
- isHidden[cannibals[i]] = false
- end
- AnimSetGearPosition(cannibals[i], unpack(cannibalPos[i]))
- SetState(cannibals[i], 0)
- end
- if cyborgHidden == true then
- RestoreHog(cyborg)
- cyborgHidden = false
- end
- SetState(cyborg, 0)
- SetState(dense, 0)
- AnimSetGearPosition(dense, 1350, 1315)
- FollowGear(dense)
- HogTurnLeft(dense, true)
- AnimSetGearPosition(cyborg, 1250, 1315)
- SwitchHog(dense)
- SetInputMask(0xFFFFFFFF)
-end
-
-function RestartReturnAccepted()
- retryReturn = false
- AnimSetGearPosition(dense, 1350, 1310)
- AddAmmo(dense, amGirder, 2)
- AddAmmo(dense, amParachute, 2)
- ShowMission(loc("The Shadow Falls"), loc("The walk of Fame"), loc("Return to Leaks A Lot! If you get stuck, press [Precise] to try again!"), 1, 6000)
- RemoveEventFunc(CheckNeedGirder)
- RemoveEventFunc(CheckNeedWeapons)
- AddEvent(CheckNeedGirder, {}, DoNeedGirder, {}, 0)
- AddEvent(CheckNeedWeapons, {}, DoNeedWeapons, {}, 0)
-end
-
-
-function AfterAcceptedAnim()
- stage = acceptedReturnStage
- SpawnAmmoCrate(1370, 810, amGirder)
- SpawnAmmoCrate(1300, 810, amParachute)
- ShowMission(loc("The Shadow Falls"), loc("The walk of Fame"), loc("Return to Leaks A Lot! If you get stuck, press [Precise] to try again!"), 1, 6000)
- AddEvent(CheckTookWeapons, {}, DoTookWeapons, {}, 0)
- AddEvent(CheckNeedGirder, {}, DoNeedGirder, {}, 0)
- AddEvent(CheckNeedWeapons, {}, DoNeedWeapons, {}, 0)
- AddEvent(CheckRestartReturnAccepted, {}, RestartReturnAccepted, {}, 1)
- RemoveEventFunc(CheckDenseDead)
- SwitchHog(dense)
- AnimWait(dense, 1)
- AddFunction({func = HideHog, args = {cyborg}})
-end
-
-function SkipAcceptedAnim()
- AnimSetGearPosition(cyborg, unpack(cyborgPos))
- SetState(cyborg, gstInvisible)
- AnimSwitchHog(dense)
- SetInputMask(0xFFFFFFFF)
-end
-
-function AfterAttackedAnim()
- stage = aloneStage
- ShowMission(loc("The Shadow Falls"), loc("The Individualist"), loc("Defeat the cannibals!|Grenade hint: set the timer with [1-5], aim with [Up]/[Down] and hold [Space] to set power"), 1, 8000)
- AddAmmo(cannibals[6], amGrenade, 1)
- AddAmmo(cannibals[6], amFirePunch, 0)
- AddAmmo(cannibals[6], amBaseballBat, 0)
- AddAmmo(cannibals[7], amGrenade, 1)
- AddAmmo(cannibals[7], amFirePunch, 0)
- AddAmmo(cannibals[7], amBaseballBat, 0)
- AddAmmo(cannibals[8], amGrenade, 1)
- AddAmmo(cannibals[8], amFirePunch, 0)
- AddAmmo(cannibals[8], amBaseballBat, 0)
- AddAmmo(cannibals[9], amGrenade, 1)
- AddAmmo(cannibals[9], amFirePunch, 0)
- AddAmmo(cannibals[9], amBaseballBat, 0)
- SetGearMessage(leaks, 0)
- TurnTimeLeft = TurnTime
- AddEvent(CheckStronglingsDead, {}, DoStronglingsDeadAttacked, {}, 0)
- SwitchHog(leaks)
- AnimWait(dense, 1)
- AddFunction({func = HideHog, args = {cyborg}})
-end
-
-function SkipAttackedAnim()
- if denseDead == false then
- DeleteGear(dense)
- end
- SpawnAmmoCrate(2551, 994, amGrenade)
- SpawnAmmoCrate(3551, 994, amGrenade)
- SpawnAmmoCrate(3392, 1101, amShotgun)
- SpawnAmmoCrate(3192, 1101, amShotgun)
- AnimSetGearPosition(cyborg, unpack(cyborgPos))
- SetState(cyborg, gstInvisible)
- AnimSwitchHog(leaks)
- SetInputMask(0xFFFFFFFF)
-end
-
-
------------------------------Animations--------------------------------
-
-function SpawnCrates()
- SpawnAmmoCrate(2551, 994, amGrenade)
- SpawnAmmoCrate(3551, 994, amGrenade)
- SpawnAmmoCrate(3392, 1101, amShotgun)
- SpawnAmmoCrate(3192, 1101, amShotgun)
- return true
-end
-
-function EmitDenseClouds(anim, dir)
- local dif
- if dir == "Left" then
- dif = 10
- else
- dif = -10
- end
- AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
- AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
- AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
- AnimInsertStepNext({func = AnimWait, args = {dense, 800}})
- AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
- AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
- AnimInsertStepNext({func = AnimWait, args = {dense, 800}})
- AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
-end
-
-function BlowDenseCloud()
- AnimInsertStepNext({func = DeleteGear, args = {dense}, swh = false})
- AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense), GetY(dense), vgtBigExplosion, 0, true}, swh = false})
- AnimInsertStepNext({func = AnimWait, args = {dense, 1200}})
- AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + 20, GetY(dense), vgtExplosion, 0, true}, swh = false})
- AnimInsertStepNext({func = AnimWait, args = {dense, 100}})
- AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + 10, GetY(dense), vgtExplosion, 0, true}, swh = false})
- AnimInsertStepNext({func = AnimWait, args = {dense, 100}})
- AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) - 10, GetY(dense), vgtExplosion, 0, true}, swh = false})
- AnimInsertStepNext({func = AnimWait, args = {dense, 100}})
- AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) - 20, GetY(dense), vgtExplosion, 0, true}, swh = false})
-end
-
-function SetupAcceptedSurvivedFinalAnim()
- table.insert(acceptedSurvivedFinalAnim, {func = AnimCustomFunction, args = {dense, CondNeedToTurn, {leaks, dense}}})
- table.insert(acceptedSurvivedFinalAnim, {func = AnimSay, args = {leaks, loc("Pfew! That was close!"), SAY_SAY, 3000}})
- if grenadeUsed and shotgunUsed then
- table.insert(acceptedSurvivedFinalAnim, {func = AnimSay, args = {leaks, loc("Where did you get the exploding apples and the magic bow that shoots many arrows?"), SAY_SAY, 9000}})
- elseif grenadeUsed then
- table.insert(acceptedSurvivedFinalAnim, {func = AnimSay, args = {leaks, loc("Where did you get the exploding apples?"), SAY_SAY, 6000}})
- elseif shotgunUsed then
- table.insert(acceptedSurvivedFinalAnim, {func = AnimSay, args = {leaks, loc("Where did you get the magic bow that shoots many arrows?"), SAY_SAY, 8000}})
- else
- table.insert(acceptedSurvivedFinalAnim, {func = AnimSay, args = {leaks, loc("Did you warn the village?"), SAY_SAY, 4000}})
- table.insert(acceptedSurvivedFinalAnim, {func = AnimSay, args = {dense, loc("No, I came back to help you out..."), SAY_SAY, 5000}})
- end
- if grenadeUsed or shotgunUsed then
- table.insert(acceptedSurvivedFinalAnim, {func = AnimSay, args = {dense, loc("Uhm...I met one of them and took his weapons."), SAY_SAY, 5000}})
- end
- table.insert(acceptedSurvivedFinalAnim, {func = AnimSay, args = {dense, loc("We should head back to the village now."), SAY_SAY, 5000}})
-end
-
-function AnimationSetup()
- table.insert(startDialogue, {func = AnimWait, args = {dense, 4000}})
- table.insert(startDialogue, {func = AnimCaption, args = {leaks, loc("After the shock caused by the enemy spy, Leaks A Lot and Dense Cloud went hunting to relax."), 6000}})
- table.insert(startDialogue, {func = AnimCaption, args = {leaks, loc("Little did they know that this hunt will mark them forever..."), 4000}})
- table.insert(startDialogue, {func = AnimSay, args = {leaks, loc("I have no idea where that mole disappeared...Can you see it?"), SAY_SAY, 9000}})
- table.insert(startDialogue, {func = AnimSay, args = {dense, loc("Nope. It was one fast mole, that's for sure."), SAY_SAY, 5000}})
- table.insert(startDialogue, {func = AnimCustomFunction, args = {dense, EmitDenseClouds, {startDialogue, "Right"}}})
- table.insert(startDialogue, {func = AnimWait, args = {dense, 2000}})
- table.insert(startDialogue, {func = AnimSay, args = {leaks, loc("Please, stop releasing your \"smoke signals\"!"), SAY_SAY, 5000}})
- table.insert(startDialogue, {func = AnimSay, args = {leaks, loc("You're terrorizing the forest...We won't catch anything like this!"), SAY_SAY, 6000}})
- table.insert(startDialogue, {func = AnimSay, args = {leaks, loc("..."), SAY_THINK, 1000}})
- table.insert(startDialogue, {func = AnimGiveState, args = {cannibals[1], 0}, swh = false})
- table.insert(startDialogue, {func = AnimOutOfNowhere, args = {cannibals[1], unpack(cannibalPos[1])}, swh = false})
- table.insert(startDialogue, {func = AnimTurn, args = {leaks, "Right"}})
- table.insert(startDialogue, {func = AnimTurn, args = {cannibals[1], "Right"}})
- table.insert(startDialogue, {func = AnimWait, args = {cannibals[1], 1000}})
- table.insert(startDialogue, {func = AnimTurn, args = {cannibals[1], "Left"}})
- table.insert(startDialogue, {func = AnimWait, args = {cannibals[1], 1000}})
- table.insert(startDialogue, {func = AnimTurn, args = {cannibals[1], "Right"}})
- table.insert(startDialogue, {func = AnimSay, args = {cannibals[1], loc("I can't believe it worked!"), SAY_THINK, 3500}})
- table.insert(startDialogue, {func = AnimSay, args = {cannibals[1], loc("That shaman sure knows what he's doing!"), SAY_THINK, 6000}})
- table.insert(startDialogue, {func = AnimSay, args = {cannibals[1], loc("Yeah...I think it's a 'he', lol."), SAY_THINK, 5000}})
- table.insert(startDialogue, {func = AnimSay, args = {leaks, loc("It wants our brains!"), SAY_SHOUT, 3000}})
- table.insert(startDialogue, {func = AnimTurn, args = {cannibals[1], "Left"}})
- table.insert(startDialogue, {func = AnimSay, args = {cannibals[1], loc("Not you again! My head still hurts from last time!"), SAY_SHOUT, 6000}})
- table.insert(startDialogue, {func = AnimSwitchHog, args = {leaks}})
- AddSkipFunction(startDialogue, StartSkipFunc, {})
-
- table.insert(weaklingsAnim, {func = AnimGearWait, args = {leaks, 1000}})
- table.insert(weaklingsAnim, {func = AnimCustomFunction, args = {leaks, CondNeedToTurn, {leaks, dense}}})
- table.insert(weaklingsAnim, {func = AnimSay, args = {leaks, loc("Did you see him coming?"), SAY_SAY, 3500}})
- table.insert(weaklingsAnim, {func = AnimSay, args = {dense, loc("No. Where did he come from?"), SAY_SAY, 3500}})
- table.insert(weaklingsAnim, {func = AnimCustomFunction, args = {leaks, UnHideWeaklings, {}}})
- table.insert(weaklingsAnim, {func = AnimOutOfNowhere, args = {cannibals[2], unpack(cannibalPos[2])}})
- table.insert(weaklingsAnim, {func = AnimGiveState, args = {cannibals[2], 0}})
- table.insert(weaklingsAnim, {func = AnimWait, args = {leaks, 400}})
- table.insert(weaklingsAnim, {func = AnimGiveState, args = {cannibals[3], 0}})
- table.insert(weaklingsAnim, {func = AnimOutOfNowhere, args = {cannibals[3], unpack(cannibalPos[3])}})
- table.insert(weaklingsAnim, {func = AnimWait, args = {leaks, 400}})
- table.insert(weaklingsAnim, {func = AnimGiveState, args = {cannibals[4], 0}})
- table.insert(weaklingsAnim, {func = AnimOutOfNowhere, args = {cannibals[4], unpack(cannibalPos[4])}})
- table.insert(weaklingsAnim, {func = AnimWait, args = {leaks, 400}})
- table.insert(weaklingsAnim, {func = AnimGiveState, args = {cannibals[5], 0}})
- table.insert(weaklingsAnim, {func = AnimOutOfNowhere, args = {cannibals[5], unpack(cannibalPos[5])}})
- table.insert(weaklingsAnim, {func = AnimWait, args = {leaks, 400}})
- table.insert(weaklingsAnim, {func = AnimSay, args = {cannibals[3], loc("Are we there yet?"), SAY_SAY, 4000}})
- table.insert(weaklingsAnim, {func = AnimSay, args = {dense, loc("This must be some kind of sorcery!"), SAY_SHOUT, 3500}})
- table.insert(weaklingsAnim, {func = AnimSwitchHog, args = {leaks}})
- AddSkipFunction(weaklingsAnim, SkipWeaklingsAnim, {})
-
- table.insert(stronglingsAnim, {func = AnimGearWait, args = {leaks, 1000}})
- table.insert(stronglingsAnim, {func = AnimCustomFunction, args = {leaks, UnHideStronglings, {}}})
- table.insert(stronglingsAnim, {func = AnimCustomFunction, args = {leaks, CondNeedToTurn, {leaks, dense}}})
- table.insert(stronglingsAnim, {func = AnimGiveState, args = {leaks, 0}})
- table.insert(stronglingsAnim, {func = AnimGiveState, args = {dense, 0}})
- table.insert(stronglingsAnim, {func = AnimSay, args = {leaks, loc("I thought their shaman died when he tried our medicine!"), SAY_SAY, 7000}})
- table.insert(stronglingsAnim, {func = AnimSay, args = {dense, loc("I saw it with my own eyes!"), SAY_SAY, 4000}})
- table.insert(stronglingsAnim, {func = AnimSay, args = {leaks, loc("Then how do they keep appearing?"), SAY_SAY, 4000}})
- table.insert(stronglingsAnim, {func = AnimSay, args = {leaks, loc("It's impossible to communicate with the spirits without a shaman."), SAY_SAY, 7000}})
- table.insert(stronglingsAnim, {func = AnimSay, args = {dense, loc("We need to warn the village."), SAY_SAY, 3500}})
- table.insert(stronglingsAnim, {func = AnimGiveState, args = {cannibals[6], 0}})
- table.insert(stronglingsAnim, {func = AnimOutOfNowhere, args = {cannibals[6], unpack(cannibalPos[6])}})
- table.insert(stronglingsAnim, {func = AnimWait, args = {leaks, 400}})
- table.insert(stronglingsAnim, {func = AnimGiveState, args = {cannibals[7], 0}})
- table.insert(stronglingsAnim, {func = AnimOutOfNowhere, args = {cannibals[7], unpack(cannibalPos[7])}})
- table.insert(stronglingsAnim, {func = AnimWait, args = {leaks, 400}})
- table.insert(stronglingsAnim, {func = AnimGiveState, args = {cannibals[8], 0}})
- table.insert(stronglingsAnim, {func = AnimOutOfNowhere, args = {cannibals[8], unpack(cannibalPos[8])}})
- table.insert(stronglingsAnim, {func = AnimWait, args = {leaks, 400}})
- table.insert(stronglingsAnim, {func = AnimGiveState, args = {cannibals[9], 0}})
- table.insert(stronglingsAnim, {func = AnimOutOfNowhere, args = {cannibals[9], unpack(cannibalPos[9])}})
- table.insert(stronglingsAnim, {func = AnimWait, args = {leaks, 400}})
- table.insert(stronglingsAnim, {func = AnimSay, args = {cannibals[7], loc("What a ride!"), SAY_SHOUT, 2000}})
- table.insert(stronglingsAnim, {func = AnimTurn, args = {leaks, "Right"}})
- table.insert(stronglingsAnim, {func = AnimWait, args = {leaks, 700}})
- table.insert(stronglingsAnim, {func = AnimTurn, args = {leaks, "Left"}})
- table.insert(stronglingsAnim, {func = AnimSay, args = {leaks, loc("We can't defeat them!"), SAY_THINK, 3000}})
- table.insert(stronglingsAnim, {func = AnimSay, args = {leaks, loc("I'll hold them off while you return to the village!"), SAY_SAY, 6000}})
- table.insert(stronglingsAnim, {func = AnimFollowGear, args = {cyborg}, swh = false})
- table.insert(stronglingsAnim, {func = AnimCaption, args = {cyborg, loc("30 minutes later...")}, swh = false})
- table.insert(stronglingsAnim, {func = AnimWait, args = {cyborg, 2000}})
- table.insert(stronglingsAnim, {func = AnimSetGearPosition, args = {dense, 1420, 1315}})
- table.insert(stronglingsAnim, {func = AnimMove, args = {dense, "Left", 1400, 0}})
- table.insert(stronglingsAnim, {func = AnimCustomFunction, args = {dense, EmitDenseClouds, {stronglingsAnim, "Left"}}})
- table.insert(stronglingsAnim, {func = AnimMove, args = {dense, "Left", 1350, 0}})
- table.insert(stronglingsAnim, {func = AnimOutOfNowhere, args = {cyborg, 1250, 1320}})
- table.insert(stronglingsAnim, {func = AnimRemoveState, args = {cyborg, gstInvisible}})
- table.insert(stronglingsAnim, {func = AnimGearWait, args = {cyborg, 2000}})
- table.insert(stronglingsAnim, {func = AnimSay, args = {cyborg, loc("Greetings, cloudy one!"), SAY_SAY, 3000}})
- table.insert(stronglingsAnim, {func = AnimSay, args = {cyborg, loc("I have come to make you an offering..."), SAY_SAY, 6000}})
- table.insert(stronglingsAnim, {func = AnimSay, args = {cyborg, loc("You are given the chance to turn your life around..."), SAY_SAY, 6000}})
- table.insert(stronglingsAnim, {func = AnimSay, args = {cyborg, loc("If you agree to provide the information we need, you will be spared!"), SAY_SAY, 7000}})
- table.insert(stronglingsAnim, {func = AnimSay, args = {cyborg, loc("Have no illusions, your tribe is dead, indifferent of your choice."), SAY_SAY, 7000}})
- table.insert(stronglingsAnim, {func = AnimSay, args = {cyborg, loc("If you decide to help us, though, we will no longer need to find a new governor for the island."), SAY_SAY, 8000}})
- table.insert(stronglingsAnim, {func = AnimSay, args = {cyborg, loc("If you know what I mean..."), SAY_SAY, 3000}})
- table.insert(stronglingsAnim, {func = AnimSay, args = {cyborg, loc("So? What will it be?"), SAY_SAY, 3000}})
- table.insert(stronglingsAnim, {func = AnimSwitchHog, args = {dense}})
- AddSkipFunction(stronglingsAnim, SkipStronglingsAnim, {})
-
- table.insert(acceptedAnim, {func = AnimSay, args = {cyborg, loc("Great choice, Steve! Mind if I call you that?"), SAY_SAY, 7000}})
- table.insert(acceptedAnim, {func = AnimSay, args = {dense, loc("Whatever floats your boat..."), SAY_SAY, 4500}})
- table.insert(acceptedAnim, {func = AnimSay, args = {cyborg, loc("Great! You will be contacted soon for assistance."), SAY_SAY, 6000}})
- table.insert(acceptedAnim, {func = AnimSay, args = {cyborg, loc("In the meantime, take these and return to your \"friend\"!"), SAY_SAY, 6000}})
- table.insert(acceptedAnim, {func = AnimGiveState, args = {cyborg, gstInvisible}})
- table.insert(acceptedAnim, {func = AnimDisappear, args = {cyborg, unpack(cyborgPos)}})
- table.insert(acceptedAnim, {func = AnimSwitchHog, args = {dense}})
- AddSkipFunction(acceptedAnim, SkipAcceptedAnim, {})
-
- table.insert(acceptedDiedFinalAnim, {func = AnimSay, args = {leaks, loc("Pfew! That was close!"), SAY_THINK, 3000}})
- table.insert(acceptedDiedFinalAnim, {func = AnimSay, args = {leaks, loc("Your death will not be in vain, Dense Cloud!"), SAY_THINK, 5000}})
- table.insert(acceptedDiedFinalAnim, {func = AnimSay, args = {dense, loc("You will be avenged!"), SAY_SAY, 3000}})
-
- table.insert(refusedAnim, {func = AnimSay, args = {cyborg, loc("I see..."), SAY_SAY, 2000}})
- table.insert(refusedAnim, {func = AnimSay, args = {cyborg, loc("Remember this, pathetic animal: when the day comes, you will regret your blind loyalty!"), SAY_SAY, 8000}})
- table.insert(refusedAnim, {func = AnimSay, args = {cyborg, loc("You just committed suicide..."), SAY_SAY, 5000}})
- table.insert(refusedAnim, {func = AnimDisappear, args = {cyborg, unpack(cyborgPos)}})
- table.insert(refusedAnim, {func = AnimGiveState, args = {cyborg, gstInvisible}})
- table.insert(refusedAnim, {func = AnimSay, args = {dense, loc("If you say so..."), SAY_THINK, 3000}})
- table.insert(refusedAnim, {func = AnimFollowGear, args = {cyborg}, swh = false})
- table.insert(refusedAnim, {func = AnimWait, args = {cyborg, 700}})
- table.insert(refusedAnim, {func = AnimCustomFunction, args = {dense, RefusedStart, {}}})
- table.insert(refusedAnim, {func = AnimOutOfNowhere, args = {dense, 2645, 1146}})
- table.insert(refusedAnim, {func = AnimOutOfNowhere, args = {ramon, 2218, 1675}})
- table.insert(refusedAnim, {func = AnimOutOfNowhere, args = {spiky, 2400, 1675}})
- table.insert(refusedAnim, {func = AnimTurn, args = {spiky, "Left"}})
- table.insert(refusedAnim, {func = AnimWait, args = {cyborg, 1700}})
- table.insert(refusedAnim, {func = AnimTurn, args = {spiky, "Right"}})
- table.insert(refusedAnim, {func = AnimWait, args = {cyborg, 1700}})
- table.insert(refusedAnim, {func = AnimTurn, args = {spiky, "Left"}})
- table.insert(refusedAnim, {func = AnimSay, args = {spiky, loc("Dude, we really need a new shaman..."), SAY_SAY, 4000}})
- AddSkipFunction(refusedAnim, SkipRefusedAnim, {})
-
- table.insert(refusedFinalAnim, {func = AnimSay, args = {leaks, loc("It's over..."), SAY_SAY, 2000}})
- table.insert(refusedFinalAnim, {func = AnimSay, args = {leaks, loc("Let's head back to the village!"), SAY_SAY, 4000}})
-
- table.insert(attackedAnim, {func = AnimCustomFunction, args = {dense, CondNeedToTurn, {cyborg, dense}}})
- table.insert(attackedAnim, {func = AnimCustomFunction, args = {cyborg, SetHealth, {cyborg, 200}}})
- table.insert(attackedAnim, {func = AnimWait, args = {cyborg, 2000}})
- table.insert(attackedAnim, {func = AnimSay, args = {cyborg, loc("Really?! You thought you could harm me with your little toys?"), SAY_SAY, 7000}})
- table.insert(attackedAnim, {func = AnimSay, args = {cyborg, loc("You're pathetic! You are not worthy of my attention..."), SAY_SAY, 6000}})
- table.insert(attackedAnim, {func = AnimSay, args = {cyborg, loc("Actually, you aren't worthy of life! Take this..."), SAY_SAY, 5000}})
- table.insert(attackedAnim, {func = AnimCustomFunction, args = {dense, BlowDenseCloud, {}}, swh = false})
- table.insert(attackedAnim, {func = AnimWait, args = {cyborg, 2000}})
- table.insert(attackedAnim, {func = AnimSay, args = {cyborg, loc("Incredible..."), SAY_SAY, 3000}})
- table.insert(attackedAnim, {func = AnimDisappear, args = {cyborg, unpack(cyborgPos)}})
- table.insert(attackedAnim, {func = AnimGiveState, args = {cyborg, gstInvisible}})
- table.insert(attackedAnim, {func = AnimSwitchHog, args = {leaks}})
- table.insert(attackedAnim, {func = AnimSay, args = {leaks, loc("I wonder where Dense Cloud is..."), SAY_THINK, 4000}})
- table.insert(attackedAnim, {func = AnimSay, args = {leaks, loc("I can't wait any more, I have to save myself!"), SAY_THINK, 5000}})
- table.insert(attackedAnim, {func = AnimCustomFunction, args = {leaks, SpawnCrates, {}}})
- table.insert(attackedAnim, {func = AnimWait, args = {leaks, 1500}})
- table.insert(attackedAnim, {func = AnimSay, args = {leaks, loc("Where are all these crates coming from?!"), SAY_THINK, 5500}})
- AddSkipFunction(attackedAnim, SkipAttackedAnim, {})
-
- table.insert(attackedFinalAnim, {func = AnimWait, args = {leaks, 2000}})
- table.insert(attackedFinalAnim, {func = AnimSay, args = {leaks, loc("I have to get back to the village!"), SAY_THINK, 5000}})
- table.insert(attackedFinalAnim, {func = AnimSay, args = {leaks, loc("Dense Cloud must have already told them everything..."), SAY_THINK, 7000}})
-
-end
-
-
------------------------------Misc--------------------------------------
-
-
-function RefusedStart()
- if ramonHidden == true then
- RestoreHog(ramon)
- ramonHidden = false
- end
- if spikyHidden == true then
- RestoreHog(spiky)
- spikyHidden = false
- end
- SetState(ramon, 0)
- SetState(spiky, 0)
- SetGearMessage(dense, 0)
- SetGearMessage(ramon, 0)
- SetGearMessage(spiky, 0)
-end
-
-function AddHogs()
- AddTeam(loc("Natives"), 29439, "Bone", "Island", "HillBilly", "cm_birdy")
- ramon = AddHog(loc("Ramon"), 0, 100, "rasta")
- leaks = AddHog(loc("Leaks A Lot"), 0, 100, "Rambo")
- dense = AddHog(loc("Dense Cloud"), 0, 100, "RobinHood")
- spiky = AddHog(loc("Spiky Cheese"), 0, 100, "hair_yellow")
-
- AddTeam(loc("Weaklings"), 14483456, "Skull", "Island", "Pirate","cm_vampire")
- cannibals = {}
- cannibals[1] = AddHog(loc("Brainiac"), 5, 20, "Zombi")
-
- for i = 2, 5 do
- cannibals[i] = AddHog(HogNames[i], 1, 20, "Zombi")
- hogNr[cannibals[i]] = i - 2
- end
-
- AddTeam(loc("Stronglings"), 14483456, "Skull", "Island", "Pirate","cm_vampire")
-
- for i = 6, 9 do
- cannibals[i] = AddHog(HogNames[i], 2, 30, "vampirichog")
- hogNr[cannibals[i]] = i - 2
- end
-
- AddTeam(loc("011101001"), 14483456, "ring", "UFO", "Robot", "cm_star")
- cyborg = AddHog(loc("Y3K1337"), 0, 200, "cyborg1")
-end
-
-function PlaceHogs()
- HogTurnLeft(leaks, true)
-
- for i = 2, 9 do
- AnimSetGearPosition(cannibals[i], unpack(cyborgPos))
- AnimTurn(cannibals[i], "Left")
- cannibalDead[i] = false
- end
-
- AnimSetGearPosition(cannibals[1], cannibalPos[1][1], cannibalPos[1][2])
- AnimTurn(cannibals[1], "Left")
-
- AnimSetGearPosition(cyborg, cyborgPos[1], cyborgPos[2])
- AnimSetGearPosition(ramon, 2218, 1675)
- AnimSetGearPosition(skiky, 2400, 1675)
- AnimSetGearPosition(dense, densePos[1], densePos[2])
- AnimSetGearPosition(leaks, leaksPos[1], leaksPos[2])
-end
-
-function VisiblizeHogs()
- for i = 1, 9 do
- SetState(cannibals[i], gstInvisible)
- end
- SetState(cyborg, gstInvisible)
- SetState(ramon, gstInvisible)
- SetState(spiky, gstInvisible)
-end
-
-function CondNeedToTurn(hog1, hog2)
- xl, xd = GetX(hog1), GetX(hog2)
- if xl > xd then
- AnimInsertStepNext({func = AnimTurn, args = {hog1, "Left"}})
- AnimInsertStepNext({func = AnimTurn, args = {hog2, "Right"}})
- elseif xl < xd then
- AnimInsertStepNext({func = AnimTurn, args = {hog2, "Left"}})
- AnimInsertStepNext({func = AnimTurn, args = {hog1, "Right"}})
- end
-end
-
-function HideHogs()
- for i = 2, 9 do
- HideHog(cannibals[i])
- isHidden[cannibals[i]] = true
- end
- HideHog(cyborg)
- cyborgHidden = true
- HideHog(ramon)
- HideHog(spiky)
- ramonHidden = true
- spikyHidden = true
-end
-
-function HideStronglings()
- for i = 6, 9 do
- HideHog(cannibals[i])
- isHidden[cannibals[i]] = true
- end
-end
-
-function UnHideWeaklings()
- for i = 2, 5 do
- RestoreHog(cannibals[i])
- isHidden[cannibals[i]] = false
- SetState(cannibals[i], gstInvisible)
- end
-end
-
-function UnHideStronglings()
- for i = 6, 9 do
- RestoreHog(cannibals[i])
- isHidden[cannibals[i]] = false
- SetState(cannibals[i], gstInvisible)
- end
- RestoreHog(cyborg)
- cyborgHidden = false
- SetState(cyborg, gstInvisible)
-end
-
-function ChoiceTaken()
- SetGearMessage(CurrentHedgehog, 0)
- if choice == choiceAccept then
- AddAnim(acceptedAnim)
- AddFunction({func = AfterAcceptedAnim, args = {}})
- elseif choice == choiceRefuse then
- AddAnim(refusedAnim)
- AddFunction({func = AfterRefusedAnim, args = {}})
- else
- AddAnim(attackedAnim)
- AddFunction({func = AfterAttackedAnim, args = {}})
- end
-end
-
-function KillCyborg()
- RestoreHog(cyborg)
- DeleteGear(cyborg)
- TurnTimeLeft = 0
-end
------------------------------Events------------------------------------
-
-function CheckBrainiacDead()
- return brainiacDead
-end
-
-function DoBrainiacDead()
- TurnTimeLeft = 0
- SetGearMessage(CurrentHedgehog, 0)
- AddAnim(weaklingsAnim)
- AddFunction({func = AfterWeaklingsAnim, args = {}})
- stage = interSpyStage
-end
-
-function CheckWeaklingsKilled()
- for i = 2, 5 do
- if cannibalDead[i] == false then
- return false
- end
- end
- return true
-end
-
-function DoWeaklingsKilled()
- SetGearMessage(CurrentHedgehog, 0)
- AddAnim(stronglingsAnim)
- AddFunction({func = AfterStronglingsAnim, args = {}})
- stage = interWeakStage
- ParseCommand("teamgone " .. loc("Weaklings"))
-end
-
-function CheckRefuse()
- return GetX(dense) > 1400 and StoppedGear(dense)
-end
-
-function DoRefuse()
- choice = choiceRefuse
-end
-
-function CheckAccept()
- return GetX(dense) < 1300 and StoppedGear(dense)
-end
-
-function DoAccept()
- choice = choiceAccept
-end
-
-function CheckConfront()
- return cyborgAttacked and StoppedGear(dense)
-end
-
-function DoConfront()
- choice = choiceAttack
-end
-
-function CheckChoice()
- return choice ~= 0
-end
-
-function DoChoice()
- RemoveEventFunc(CheckConfront)
- RemoveEventFunc(CheckAccept)
- RemoveEventFunc(CheckRefuse)
- ChoiceTaken()
-end
-
-function CheckNeedGirder()
- return GetX(dense) > 1640 and StoppedGear(dense)
-end
-
-function DoNeedGirder()
- ShowMission(loc("The Shadow Falls"), loc("Under Construction"), loc("To place a girder, select it, use [Left] and [Right] to select angle and length, place with [Left Click]"), 1, 6000)
-end
-
-function CheckNeedWeapons()
- return GetX(dense) > 2522 and StoppedGear(dense)
-end
-
-function DoNeedWeapons()
- grenadeCrate = SpawnAmmoCrate(2550, 800, amGrenade)
- shotgunCrate = SpawnAmmoCrate(2610, 850, amShotgun)
- AddCaption(loc("A little gift from the cyborgs"))
-end
-
-function CheckTookWeapons()
- return shotgunTaken and grenadeTaken
-end
-
-function DoTookWeapons()
- ShowMission(loc("The Shadow Falls"), loc("The guardian"), loc("Protect yourselves!|Grenade hint: set the timer with [1-5], aim with [Up]/[Down] and hold [Space] to set power"), 1, 8000)
- AddAmmo(dense, amSkip, 100)
- AddAmmo(dense, amSwitch, 100)
- AddAmmo(leaks, amSkip, 100)
- AddAmmo(leaks, amSwitch, 100)
- stage = duoStage
- RemoveEventFunc(CheckNeedGirder)
- RemoveEventFunc(CheckNeedWeapons)
- RemoveEventFunc(CheckRestartReturnAccepted)
- AddEvent(CheckStronglingsDead, {}, DoStronglingsDead, {}, 0)
- AddAmmo(cannibals[6], amGrenade, 2)
- AddAmmo(cannibals[6], amShotgun, 2)
- AddAmmo(cannibals[7], amGrenade, 2)
- AddAmmo(cannibals[7], amShotgun, 2)
- AddAmmo(cannibals[8], amGrenade, 2)
- AddAmmo(cannibals[8], amShotgun, 2)
- AddAmmo(cannibals[9], amGrenade, 2)
- AddAmmo(cannibals[9], amShotgun, 2)
- SetGearMessage(leaks, 0)
- SetGearMessage(dense, 0)
- TurnTimeLeft = TurnTime
-end
-
-function DoStronglingsDead()
- SetGearMessage(CurrentHedgehog, 0)
- if denseDead == true then
- AddAnim(acceptedDiedFinalAnim)
- SaveCampaignVar("M2DenseDead", "1")
- else
- SetupAcceptedSurvivedFinalAnim()
- AddAnim(acceptedSurvivedFinalAnim)
- SaveCampaignVar("M2DenseDead", "0")
- end
- SaveCampaignVar("M2RamonDead", "0")
- SaveCampaignVar("M2SpikyDead", "0")
- AddFunction({func = KillCyborg, args = {}})
- if progress and progress<2 then
- SaveCampaignVar("Progress", "2")
- end
- SaveCampaignVar("M2Choice", "" .. choice)
-end
-
-function DoStronglingsDeadRefused()
- if denseDead == true then
- SaveCampaignVar("M2DenseDead", "1")
- else
- SaveCampaignVar("M2DenseDead", "0")
- end
- if ramonDead == true then
- SaveCampaignVar("M2RamonDead", "1")
- else
- SaveCampaignVar("M2RamonDead", "0")
- end
- if spikyDead == true then
- SaveCampaignVar("M2SpikyDead", "1")
- else
- SaveCampaignVar("M2SpikyDead", "0")
- end
- AddAnim(refusedFinalAnim)
- AddFunction({func = KillCyborg, args = {}})
- if progress and progress<2 then
- SaveCampaignVar("Progress", "2")
- end
- SaveCampaignVar("M2Choice", "" .. choice)
-end
-
-function DoStronglingsDeadAttacked()
- SaveCampaignVar("M2DenseDead", "1")
- SaveCampaignVar("M2RamonDead", "0")
- SaveCampaignVar("M2SpikyDead", "0")
- if progress and progress<2 then
- SaveCampaignVar("Progress", "2")
- end
- SaveCampaignVar("M2Choice", "" .. choice)
- AddAnim(attackedFinalAnim)
- AddFunction({func = KillCyborg, args = {}})
-end
-
-function CheckStronglingsDead()
- if leaksDead == true then
- return false
- end
- for i = 6, 9 do
- if cannibalDead[i] == false then
- return false
- end
- end
- return true
-end
-
-function CheckLeaksDead()
- return leaksDead
-end
-
-function DoDead()
- AddCaption(loc("...and so the cyborgs took over the world..."))
- stage = loseStage
- TurnTimeLeft = 0
- ParseCommand("teamgone " .. loc("Natives"))
-end
-
-function CheckDenseDead()
- return denseDead and choice ~= choiceAttack
-end
-
-function CheckRestartReturnAccepted()
- return retryReturn
-end
-
------------------------------Main Functions----------------------------
-
-function onGameInit()
- Seed = 334
- GameFlags = gfSolidLand + gfDisableWind + gfPerHogAmmo
- TurnTime = 50000
- CaseFreq = 0
- MinesNum = 0
- MinesTime = 3000
- Explosives = 0
- Delay = 10
- Map = "A_Classic_Fairytale_shadow"
- Theme = "Nature"
- SuddenDeathTurns = 3000
-
- AddHogs()
- PlaceHogs()
- VisiblizeHogs()
-
- AnimInit()
- AnimationSetup()
-end
-
-function onGameStart()
- progress = tonumber(GetCampaignVar("Progress"))
- HideHogs()
- AddAmmo(leaks, amSwitch, 100)
- AddAmmo(dense, amSwitch, 100)
- AddEvent(CheckLeaksDead, {}, DoDead, {}, 0)
- AddEvent(CheckDenseDead, {}, DoDead, {}, 0)
- AddAnim(startDialogue)
- AddFunction({func = AfterStartDialogue, args = {}})
- AddEvent(CheckBrainiacDead, {}, DoBrainiacDead, {}, 0)
- ShowMission(loc("The Shadow Falls"), loc("The First Encounter"), loc("Survive!|Hint: Cinematics can be skipped with the [Precise] key."), 1, 0)
-end
-
-function onGameTick()
- AnimUnWait()
- if ShowAnimation() == false then
- return
- end
- ExecuteAfterAnimations()
- CheckEvents()
-end
-
-function onGearDelete(gear)
- if gear == cannibals[1] then
- brainiacDead = true
- elseif gear == grenadeCrate then
- grenadeTaken = true
- elseif gear == shotgunCrate then
- shotgunTaken = true
- elseif gear == dense then
- denseDead = true
- elseif gear == leaks then
- leaksDead = true
- elseif gear == ramon then
- ramonDead = true
- elseif gear == spiky then
- spikyDead = true
- else
- for i = 2, 9 do
- if gear == cannibals[i] then
- cannibalDead[i] = true
- end
- end
- end
-end
-
-function onGearAdd(gear)
- if GetGearType(gear) == gtGrenade and GetHogTeamName(CurrentHedgehog) == loc("Natives") then
- grenadeUsed = true
- elseif GetGearType(gear) == gtShotgunShot and GetHogTeamName(CurrentHedgehog) == loc("Natives") then
- shotgunUsed = true
- end
-end
-
-function onAmmoStoreInit()
- SetAmmo(amDEagle, 9, 0, 0, 0)
- SetAmmo(amSniperRifle, 6, 0, 0, 0)
- SetAmmo(amFirePunch, 3, 0, 0, 0)
- SetAmmo(amWhip, 4, 0, 0, 0)
- SetAmmo(amBaseballBat, 4, 0, 0, 0)
- SetAmmo(amHammer, 2, 0, 0, 0)
- SetAmmo(amLandGun, 1, 0, 0, 0)
- SetAmmo(amSnowball, 7, 0, 0, 0)
- SetAmmo(amGirder, 0, 0, 0, 2)
- SetAmmo(amParachute, 0, 0, 0, 2)
- SetAmmo(amGrenade, 0, 0, 0, 3)
- SetAmmo(amShotgun, 0, 0, 0, 3)
- SetAmmo(amSwitch, 0, 0, 0, 8)
- SetAmmo(amRope, 0, 0, 0, 6)
-end
-
-function onNewTurn()
- if AnimInProgress() then
- TurnTimeLeft = -1
--- elseif stage == interSpyStage and GetHogTeamName(CurrentHedgehog) ~= loc("Natives") then
--- TurnTimeLeft = 0
--- SetState(CurrentHedgehog, gstInvisible)
- elseif stage == cyborgStage then
- if CurrentHedgehog ~= dense then
- TurnTimeLeft = 0
- else
- TurnTimeLeft = -1
- end
- elseif stage == acceptedReturnStage then
- SwitchHog(dense)
- FollowGear(dense)
- TurnTimeLeft = -1
- end
-end
-
-function onGearDamage(gear, damage)
- if gear == cyborg and stage == cyborgStage then
- cyborgAttacked = true
- end
-end
-
-function onPrecise()
- if GameTime > 2500 and AnimInProgress() then
- SetAnimSkip(true)
- return
- end
- if stage == acceptedReturnStage then
- retryReturn = true
--- else
--- for i = 1, 9 do
--- DeleteGear(cannibals[i])
--- end
- end
-end
-
--- a/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/united.lua Mon Jul 01 22:28:42 2013 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,524 +0,0 @@
-HedgewarsScriptLoad("/Scripts/Locale.lua")
-HedgewarsScriptLoad("/Scripts/Animate.lua")
-
------------------------------Constants---------------------------------
-choiceAccept = 1
-choiceRefuse = 2
-choiceAttack = 3
-
-leaksPos = {2067, 509}
-densePos = {1882, 503}
-waterPos = {3100, 930}
-buffaloPos = {2609, 494}
-chiefPos = {2538, 617}
-cannibalPos = {{2219, 1339}, {2322, 1357}, {805, 784}, {3876, 1048},
- {1101, 916}, {2854, 1408}, {1974, 486}, {1103, 961}}
-
-HogNames = {loc("Olive"), loc("Brain Stu"), loc("Brainila"), loc("Salivaslurper"),
- loc("Spleenlover"), loc("Thighlicker"), loc("NomNom"), loc("Mindy")}
-
-natives = {}
------------------------------Variables---------------------------------
-cannibals = {}
-cannibalDead = {}
-cannibalHidden = {}
-cratesSpawned = {}
-healthCratesSpawned = {}
-
-sdrmv = 0
-denseDead = false
-leaksDead = false
-waterDead = false
-buffaloDead = false
-chiefDead = false
-nativesDead = {}
-
-m2Choice = 0
-m2DenseDead = 0
-
-startAnim = {}
-wave2Anim = {}
-finalAnim = {}
---------------------------Anim skip functions--------------------------
-function AfterHogDeadAnim()
- freshDead = nil
- TurnTimeLeft = TurnTime
-end
-
-function AfterStartAnim()
- local goal = loc("Defeat the cannibals!|")
- local chiefgoal = loc("Try to protect the chief! You won't lose if he dies, but it is advised that he survives.")
- TurnTimeLeft = TurnTime
- ShowMission(loc("United We Stand"), loc("Invasion"), goal .. chiefgoal, 1, 6000)
-end
-
-function SkipStartAnim()
- AnimSetGearPosition(water, 2467, 754)
- if cratesSpawned[1] ~= true then
- SpawnCrates(1)
- end
- if healthCratesSpawned[1] ~= true then
- SpawnHealthCrates(1)
- end
- if cannibalHidden[1] == true then
- RestoreWave(1)
- end
- AnimSwitchHog(leaks)
-end
-
-function SkipWave2Anim()
- if cratesSpawned[2] ~= true then
- SpawnCrates(2)
- end
- if healthCratesSpawned[2] ~= true then
- SpawnHealthCrates(2)
- end
- if cannibalHidden[5] == true then
- RestoreWave(2)
- end
- AnimSwitchHog(cannibals[5])
-end
-
-function AfterWave2Anim()
- TurnTimeLeft = 0
-end
-
-function AfterFinalAnim()
- if leaksDead == true then
- SaveCampaignVar("M4LeaksDead", "1")
- else
- SaveCampaignVar("M4LeaksDead", "0")
- end
- if chiefDead == true then
- SaveCampaignVar("M4ChiefDead", "1")
- else
- SaveCampaignVar("M4ChiefDead", "0")
- end
- if buffaloDead == true then
- SaveCampaignVar("M4BuffaloDead", "1")
- else
- SaveCampaignVar("M4BuffaloDead", "0")
- end
- if waterDead == true then
- SaveCampaignVar("M4WaterDead", "1")
- else
- SaveCampaignVar("M4WaterDead", "0")
- end
- if denseDead == true then
- SaveCampaignVar("M4DenseDead", "1")
- else
- SaveCampaignVar("M4DenseDead", "0")
- end
- if progress and progress<4 then
- SaveCampaignVar("Progress", "4")
- end
- ParseCommand("teamgone " .. loc("011101001"))
- TurnTimeLeft = 0
-end
------------------------------Animations--------------------------------
-function Wave2Reaction()
- local i = 1
- local gearr = nil
- while nativesDead[i] == true do
- i = i + 1
- end
- gearr = natives[i]
- if denseDead ~= true and band(GetState(dense), gstDrowning) == 0 then
- AnimInsertStepNext({func = AnimSay, args = {dense, loc("I'm so scared!"), SAY_SAY, 3000}})
- AnimInsertStepNext({func = AnimCustomFunction, args = {dense, EmitDenseClouds, {"Left"}}})
- AnimInsertStepNext({func = AnimTurn, args = {dense, "Left"}})
- end
- AnimInsertStepNext({func = AnimSay, args = {gearr, loc("There's more of them? When did they become so hungry?"), SAY_SHOUT, 8000}})
-end
-
-function EmitDenseClouds(dir)
- local dif
- if dir == "Left" then
- dif = 10
- else
- dif = -10
- end
- AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
- AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
- AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
- AnimInsertStepNext({func = AnimWait, args = {dense, 800}})
- AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
- AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
- AnimInsertStepNext({func = AnimWait, args = {dense, 800}})
- AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
-end
-
-function AnimationSetup()
- table.insert(startAnim, {func = AnimWait, args = {leaks, 4000}})
- table.insert(startAnim, {func = AnimCaption, args = {leaks, loc("Back in the village, after telling the villagers about the threat..."), 5000}})
- table.insert(startAnim, {func = AnimCaption, args = {leaks, loc("Their buildings were very primitive back then, even for an uncivilised island."), 7000}})
- table.insert(startAnim, {func = AnimSay, args = {chief, loc("Young one, you are telling us that they can instantly change location without a shaman?"), SAY_SAY, 8000}})
- table.insert(startAnim, {func = AnimSay, args = {chief, loc("That is, indeed, very weird..."), SAY_SAY, 3500}})
- table.insert(startAnim, {func = AnimSay, args = {buffalo, loc("If they try coming here, they can have a taste of my delicious knuckles!"), SAY_SHOUT, 8000}})
- table.insert(startAnim, {func = AnimSay, args = {buffalo, loc("Haha!"), SAY_SHOUT, 2000}})
- if denseDead == false then
- table.insert(startAnim, {func = AnimSay, args = {dense, loc("I'm not sure about that!"), SAY_SAY, 3400}})
- table.insert(startAnim, {func = AnimSay, args = {dense, loc("They have weapons we've never seen before!"), SAY_SAY, 5000}})
- table.insert(startAnim, {func = AnimSay, args = {dense, loc("Luckily, I've managed to snatch some of them."), SAY_SAY, 5000}})
- table.insert(startAnim, {func = AnimCustomFunction, args = {dense, SpawnCrates, {1}}})
- table.insert(startAnim, {func = AnimSay, args = {dense, loc("Oops...I dropped them."), SAY_SAY, 3000}})
- else
- table.insert(startAnim, {func = AnimSay, args = {leaks, loc("I'm not sure about that!"), SAY_SAY, 3400}})
- table.insert(startAnim, {func = AnimSay, args = {leaks, loc("They have weapons we've never seen before!"), SAY_SAY, 5000}})
- table.insert(startAnim, {func = AnimCustomFunction, args = {leaks, SpawnCrates, {1}}})
- table.insert(startAnim, {func = AnimWait, args = {leaks, 1000}})
- table.insert(startAnim, {func = AnimSay, args = {leaks, loc("They keep appearing like this. It's weird!"), SAY_SAY, 5000}})
- end
- table.insert(startAnim, {func = AnimSay, args = {chief, loc("Did anyone follow you?"), SAY_SAY, 3000}})
- table.insert(startAnim, {func = AnimSay, args = {leaks, loc("No, we made sure of that!"), SAY_SAY, 3500}})
- table.insert(startAnim, {func = AnimCustomFunction, args = {leaks, SpawnHealthCrates, {1}}})
- table.insert(startAnim, {func = AnimWait, args = {leaks, 1000}})
- table.insert(startAnim, {func = AnimSay, args = {chief, loc("First aid kits?!"), SAY_SAY, 3000}})
- table.insert(startAnim, {func = AnimSay, args = {leaks, loc("I've seen this before. They just appear out of thin air."), SAY_SAY, 7000}})
- table.insert(startAnim, {func = AnimMove, args = {water, "Left", 3000, 0}})
- table.insert(startAnim, {func = AnimJump, args = {water, "long"}})
- table.insert(startAnim, {func = AnimMove, args = {water, "Left", 2655, 0}})
- table.insert(startAnim, {func = AnimTurn, args = {water, "Right"}})
- table.insert(startAnim, {func = AnimJump, args = {water, "back"}})
- table.insert(startAnim, {func = AnimJump, args = {water, "back"}})
- table.insert(startAnim, {func = AnimTurn, args = {water, "Left"}})
- table.insert(startAnim, {func = AnimMove, args = {water, "Left", 2467, 754}})
- table.insert(startAnim, {func = AnimSay, args = {water, loc("Hey guys!"), SAY_SAY, 2500}})
- table.insert(startAnim, {func = AnimSay, args = {chief, loc("..."), SAY_THINK, 1500}})
- table.insert(startAnim, {func = AnimSay, args = {chief, loc("Where have you been?"), SAY_SAY, 4000}})
- table.insert(startAnim, {func = AnimSay, args = {water, loc("Just on a walk."), SAY_SAY, 3000}})
- table.insert(startAnim, {func = AnimSay, args = {chief, loc("You have chosen the perfect moment to leave."), SAY_SAY, 6000}})
- table.insert(startAnim, {func = AnimCustomFunction, args = {chief, RestoreWave, {1}}})
- for i = 1, 4 do
- table.insert(startAnim, {func = AnimOutOfNowhere, args = {cannibals[i], unpack(cannibalPos[i])}})
- end
- table.insert(startAnim, {func = AnimWait, args = {chief, 1500}})
- table.insert(startAnim, {func = AnimSay, args = {leaks, loc("HOW DO THEY KNOW WHERE WE ARE???"), SAY_SHOUT, 5000}})
- table.insert(startAnim, {func = AnimSay, args = {chief, loc("We have to protect the village!"), SAY_SAY, 5000}})
- table.insert(startAnim, {func = AnimSwitchHog, args = {leaks}})
- AddSkipFunction(startAnim, SkipStartAnim, {})
-
- table.insert(wave2Anim, {func = AnimCustomFunction, args = {leaks, RestoreWave, {2}}, swh = false})
- for i = 5, 8 do
- table.insert(wave2Anim, {func = AnimOutOfNowhere, args = {cannibals[i], unpack(cannibalPos[i])}})
- end
- table.insert(wave2Anim, {func = AnimCustomFunction, args = {leaks, Wave2Reaction, {}}, swh = false})
- table.insert(wave2Anim, {func = AnimCustomFunction, args = {leaks, SpawnCrates, {2}}, swh = false})
- table.insert(wave2Anim, {func = AnimCustomFunction, args = {leaks, SpawnHealthCrates, {2}}, swh = false})
- table.insert(wave2Anim, {func = AnimSwitchHog, args = {cannibals[5]}})
- AddSkipFunction(wave2Anim, SkipWave2Anim, {})
-end
-
-function SetupHogDeadAnim(gear)
- hogDeadAnim = {}
- if nativesNum == 0 then
- return
- end
- local hogDeadStrings = {loc("They killed ") .. gear ..loc("! You bastards!"),
- gear .. loc("! Why?!"),
- loc("That was just mean!"),
- loc("Oh no, not ") .. gear .. "!"}
- table.insert(hogDeadAnim, {func = AnimSay, args = {CurrentHedgehog, hogDeadStrings[nativesNum], SAY_SHOUT, 4000}})
-end
-
-function SetupFinalAnim()
- local found = 0
- local hogs = {}
- local i = 1
- if nativesNum >= 2 then
- while found < 2 do
- if nativesDead[i] ~= true then
- found = found + 1
- hogs[found] = natives[i]
- end
- i = i + 1
- end
- if chiefDead ~= true then
- hogs[2] = chief
- end
- table.insert(finalAnim, {func = AnimCustomFunction, args = {hogs[1], CondNeedToTurn, {hogs[1], hogs[2]}}})
- table.insert(finalAnim, {func = AnimSay, args = {hogs[1], loc("We can't hold them up much longer!"), SAY_SAY, 5000}})
- table.insert(finalAnim, {func = AnimSay, args = {hogs[1], loc("We need to move!"), SAY_SAY, 3000}})
- table.insert(finalAnim, {func = AnimSay, args = {hogs[2], loc("But where can we go?"), SAY_SAY, 3000}})
- table.insert(finalAnim, {func = AnimSay, args = {hogs[1], loc("To the caves..."), SAY_SAY, 2500}})
- table.insert(finalAnim, {func = AnimSay, args = {hogs[2], loc("Good idea, they'll never find us there!"), SAY_SAY, 5000}})
- else
- for i = 1, 5 do
- if nativesDead[i] ~= true then
- hogs[1] = natives[i]
- end
- end
- table.insert(finalAnim, {func = AnimSay, args = {hogs[1], loc("I need to move the tribe!"), SAY_THINK, 4000}})
- table.insert(finalAnim, {func = AnimSay, args = {hogs[1], loc("The caves are well hidden, they won't find us there!"), SAY_THINK, 7000}})
- end
-end
------------------------------Misc--------------------------------------
-function RestoreWave(index)
- for i = (index - 1) * 4 + 1, index * 4 do
- RestoreHog(cannibals[i])
- cannibalHidden[i] = false
- end
-end
-
-function GetVariables()
- m2DenseDead = tonumber(GetCampaignVar("M2DenseDead"))
- if m2DenseDead == 1 then
- denseDead = true
- end
- m2Choice = tonumber(GetCampaignVar("M2Choice"))
-end
-
-function SetupPlace()
- if m2DenseDead == 1 then
- sdrmv = 1
- DeleteGear(dense)
- end
- for i = 1, 8 do
- HideHog(cannibals[i])
- cannibalHidden[i] = true
- end
- HideHog(cyborg)
-end
-
-function SetupEvents()
- AddEvent(CheckWaveDead, {1}, DoWaveDead, {1}, 0)
- AddEvent(CheckWaveDead, {2}, DoWaveDead, {2}, 0)
-end
-
-function SetupAmmo()
- AddAmmo(cannibals[1], amGrenade, 4)
- AddAmmo(cannibals[1], amBazooka, 4)
- AddAmmo(cannibals[1], amShotgun, 4)
- AddAmmo(cannibals[1], amMine, 2)
- AddAmmo(cannibals[5], amGrenade, 4)
- AddAmmo(cannibals[5], amBazooka, 4)
- AddAmmo(cannibals[5], amShotgun, 4)
- AddAmmo(cannibals[5], amMine, 2)
- AddAmmo(cannibals[5], amMolotov, 2)
- AddAmmo(cannibals[5], amFlamethrower, 3)
-end
-
-function AddHogs()
- AddTeam(loc("Natives"), 29439, "Bone", "Island", "HillBilly", "cm_birdy")
- leaks = AddHog(loc("Leaks A Lot"), 0, 100, "Rambo")
- dense = AddHog(loc("Dense Cloud"), 0, 100, "RobinHood")
- water = AddHog(loc("Fiery Water"), 0, 100, "pirate_jack")
- buffalo = AddHog(loc("Raging Buffalo"), 0, 100, "zoo_Bunny")
- chief = AddHog(loc("Righteous Beard"), 0, 100, "IndianChief")
- natives = {leaks, dense, water, buffalo, chief}
- nativesNum = 5
-
- AddTeam(loc("Light Cannfantry"), 14483456, "Skull", "Island", "Pirate", "cm_vampire")
- for i = 1, 4 do
- cannibals[i] = AddHog(HogNames[i], 2, 40, "Zombi")
- end
-
- AddTeam(loc("Heavy Cannfantry"), 14483456, "Skull", "Island", "Pirate", "cm_vampire")
- for i = 5, 8 do
- cannibals[i] = AddHog(HogNames[i], 2, 55, "vampirichog")
- end
-
- AddTeam(loc("011101001"), 14483456, "ring", "UFO", "Robot", "cm_star")
- cyborg = AddHog(loc("Unit 334a$7%;.*"), 0, 200, "cyborg1")
-
- AnimSetGearPosition(leaks, unpack(leaksPos))
- AnimSetGearPosition(dense, unpack(densePos))
- AnimSetGearPosition(water, unpack(waterPos))
- HogTurnLeft(water, true)
- AnimSetGearPosition(buffalo, unpack(buffaloPos))
- HogTurnLeft(buffalo, true)
- AnimSetGearPosition(chief, unpack(chiefPos))
- HogTurnLeft(chief, true)
- AnimSetGearPosition(cyborg, 0, 0)
- for i = 1, 8 do
- AnimSetGearPosition(cannibals[i], unpack(cannibalPos[i]))
- end
-end
-
-function CondNeedToTurn(hog1, hog2)
- xl, xd = GetX(hog1), GetX(hog2)
- if xl > xd then
- AnimInsertStepNext({func = AnimTurn, args = {hog1, "Left"}})
- AnimInsertStepNext({func = AnimTurn, args = {hog2, "Right"}})
- elseif xl < xd then
- AnimInsertStepNext({func = AnimTurn, args = {hog2, "Left"}})
- AnimInsertStepNext({func = AnimTurn, args = {hog1, "Right"}})
- end
-end
-
-function SpawnHealthCrates(index)
- SetHealth(SpawnHealthCrate(0, 0), 25)
- SetHealth(SpawnHealthCrate(0, 0), 25)
- SetHealth(SpawnHealthCrate(0, 0), 25)
- healthCratesSpawned[index] = true
-end
-
-function SpawnCrates(index)
- if index == 1 then
- SpawnAmmoCrate(1943, 408, amBazooka)
- SpawnAmmoCrate(1981, 464, amGrenade)
- SpawnAmmoCrate(1957, 459, amShotgun)
- SpawnAmmoCrate(1902, 450, amDynamite)
- SpawnUtilityCrate(1982, 405, amPickHammer)
- SpawnUtilityCrate(2028, 455, amRope)
- SpawnUtilityCrate(2025, 464, amTeleport)
- else
- SpawnUtilityCrate(1982, 405, amBlowTorch)
- SpawnAmmoCrate(2171, 428, amMolotov)
- SpawnAmmoCrate(2364, 346, amFlamethrower)
- SpawnAmmoCrate(2521, 303, amBazooka)
- SpawnAmmoCrate(2223, 967, amGrenade)
- SpawnAmmoCrate(1437, 371, amShotgun)
- end
- cratesSpawned[index] = true
-end
-
------------------------------Events------------------------------------
-
-function CheckWaveDead(index)
- for i = (index - 1) * 4 + 1, index * 4 do
- if cannibalDead[i] ~= true then
- return false
- end
- end
- return true
-end
-
-function DoWaveDead(index)
- SetGearMessage(CurrentHedgehog, 0)
- SetState(CurrentHedgehog, 0)
- if index == 1 then
- AddAnim(wave2Anim)
- AddFunction({func = AfterWave2Anim, args = {}})
- elseif index == 2 then
- SetupFinalAnim()
- AddAnim(finalAnim)
- AddFunction({func = AfterFinalAnim, args = {}})
- end
-end
-
-
------------------------------Main Functions----------------------------
-
-function onGameInit()
- Seed = 1
- GameFlags = 0
- TurnTime = 60000
- CaseFreq = 0
- MinesNum = 0
- MinesTime = 3000
- Explosives = 2
- Delay = 10
- Map = "Hogville"
- Theme = "Nature"
- SuddenDeathTurns = 3000
-
- AddHogs()
- AnimInit()
-end
-
-function onGameStart()
- progress = tonumber(GetCampaignVar("Progress"))
- GetVariables()
- SetupAmmo()
- SetupPlace()
- AnimationSetup()
- SetupEvents()
- AddAnim(startAnim)
- AddFunction({func = AfterStartAnim, args = {}})
-end
-
-function onGameTick()
- AnimUnWait()
- if ShowAnimation() == false then
- return
- end
- ExecuteAfterAnimations()
- CheckEvents()
-end
-
-function onGearDelete(gear)
- if gear == dense then
- denseDead = true
- nativesNum = nativesNum - 1
- nativesDead[2] = true
- if sdrmv == 1 then
- freshDead = nil
- else
- freshDead = loc("Dense Cloud")
- end
- elseif gear == leaks then
- leaksDead = true
- nativesNum = nativesNum - 1
- nativesDead[1] = true
- freshDead = loc("Leaks A Lot")
- elseif gear == chief then
- chiefDead = true
- nativesNum = nativesNum - 1
- nativesDead[5] = true
- freshDead = loc("Righteous Beard")
- elseif gear == water then
- waterDead = true
- nativesNum = nativesNum - 1
- nativesDead[3] = true
- freshDead = loc("Fiery Water")
- elseif gear == buffalo then
- buffaloDead = true
- nativesNum = nativesNum - 1
- nativesDead[4] = true
- freshDead = loc("Raging Buffalo")
- else
- for i = 1, 8 do
- if gear == cannibals[i] then
- cannibalDead[i] = true
- end
- end
- end
-end
-
-function onAmmoStoreInit()
- SetAmmo(amDEagle, 9, 0, 0, 0)
- SetAmmo(amSniperRifle, 4, 0, 0, 0)
- SetAmmo(amFirePunch, 9, 0, 0, 0)
- SetAmmo(amWhip, 9, 0, 0, 0)
- SetAmmo(amBaseballBat, 9, 0, 0, 0)
- SetAmmo(amHammer, 9, 0, 0, 0)
- SetAmmo(amLandGun, 9, 0, 0, 0)
- SetAmmo(amSnowball, 8, 0, 0, 0)
- SetAmmo(amGirder, 4, 0, 0, 2)
- SetAmmo(amParachute, 4, 0, 0, 2)
- SetAmmo(amSwitch, 8, 0, 0, 2)
- SetAmmo(amSkip, 8, 0, 0, 0)
- SetAmmo(amRope, 5, 0, 0, 3)
- SetAmmo(amBlowTorch, 3, 0, 0, 3)
- SetAmmo(amPickHammer, 0, 0, 0, 3)
- SetAmmo(amLowGravity, 0, 0, 0, 2)
- SetAmmo(amDynamite, 0, 0, 0, 3)
- SetAmmo(amBazooka, 0, 0, 0, 4)
- SetAmmo(amGrenade, 0, 0, 0, 5)
- SetAmmo(amMine, 0, 0, 0, 2)
- SetAmmo(amMolotov, 0, 0, 0, 3)
- SetAmmo(amFlamethrower, 0, 0, 0, 3)
- SetAmmo(amShotgun, 0, 0, 0, 3)
- SetAmmo(amTeleport, 0, 0, 0, 2)
- SetAmmo(amFlamethrower, 0, 0, 0, 3)
-end
-
-function onNewTurn()
- if AnimInProgress() then
- TurnTimeLeft = -1
- return
- end
- if freshDead ~= nil and GetHogTeamName(CurrentHedgehog) == loc("Natives") then
- SetupHogDeadAnim(freshDead)
- AddAnim(hogDeadAnim)
- AddFunction({func = AfterHogDeadAnim, args = {}})
- end
-end
-
-function onPrecise()
- if GameTime > 2500 then
- SetAnimSkip(true)
- end
-end
-
--- a/share/hedgewars/Data/Missions/Campaign/A Space Adventure/CMakeLists.txt Mon Jul 01 22:28:42 2013 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-file(GLOB Config *.ini)
-file(GLOB Missions *.lua)
-file(GLOB Packs *.hwp)
-
-install(FILES
- ${Config}
- ${Missions}
- ${Packs}
- DESTINATION "${SHAREPATH}Data/Missions/Campaign/A Space Adventure")
--- a/share/hedgewars/Data/Missions/Campaign/A Space Adventure/campaign.ini Mon Jul 01 22:28:42 2013 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-MissionNum=5
-ResetRetry=1
-
-[Mission 1]
-Name=The Spacetrip
-Script=cosmos.lua
-
-[Mission 2]
-Name=Moon:The First Stop
-Script=moon01.lua
-
-[Mission 3]
-Name=FRUIT
-Script=fruit.lua
-
-[Mission 4]
-Name=DESERT
-Script=desert.lua
-
-[Mission 5]
-Name=ICE
-Script=ice.lua
Binary file share/hedgewars/Data/Missions/Campaign/A Space Adventure/cosmos.hwp has changed
--- a/share/hedgewars/Data/Missions/Campaign/A Space Adventure/cosmos.lua Mon Jul 01 22:28:42 2013 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,390 +0,0 @@
-------------------- ABOUT ----------------------
---
--- This map works as a menu for the hero hog to
--- navigate through planets. It portrays the hogs
--- planet and above the planets that he'll later
--- visit.
-
--- TODO
--- Save and Load All Check Points
--- Save hero health
--- Decide and implement if hero will use gas bombs...
--- ofc add custom stats page
--- PROBLEM : What if one makes a bad choice and wants to replay it map, how to reset?
--- POSSIBLE SOLUTIONS: In game function keys, frontend button...
-
-HedgewarsScriptLoad("/Scripts/Locale.lua")
-HedgewarsScriptLoad("/Scripts/Animate.lua")
-
------------------ VARIABLES --------------------
--- globals
-local campaignName = loc("A Space Adventure")
-local missionName = loc("Cosmos")
-local timeForGuard1ToTurn = 1000 * 5 -- 5 sec
-local timeForGuard1ToTurnLeft = timeForGuard1ToTurn
-local saucerAcquired = false
-local checkPointReached = 1 -- 1 is start of the game
--- dialogs
-local dialog01 = {}
-local dialog02 = {}
-local dialog03 = {}
-local dialog04 = {}
-local dialog05 = {}
-local dialog06 = {}
--- mission objectives
-local goals = {
- [dialog01] = {missionName, loc("Getting ready"), loc("Go and collect the crate on top of the column").."|"..loc("Use the sleep gas bomb if the guards spot you!"), 1, 4500},
- [dialog02] = {missionName, loc("The adventure begins!"), loc("Use the saucer and fly to the moon").."|"..loc("Drive carefully as your fuels are limited"), 1, 4500},
- [dialog03] = {missionName, loc("An unexpected event!"), loc("Use the saucer and fly away or use the gas bomb to neutralize the guards").."|"..loc("Beware, any damage taken will stay until you take some medicine or visit moon"), 1, 7000}
-}
--- crates
-local saucerX = 3270
-local saucerY = 1500
--- hogs
-local hero = {}
-local director = {}
-local doctor = {}
-local guard1 = {}
-local guard2 = {}
--- teams
-local teamA = {}
-local teamB = {}
-local teamC = {}
--- hedgehogs values
-hero.name = loc("Hog Solo")
-hero.x = 1450
-hero.y = 1550
-director.name = loc("H")
-director.x = 1350
-director.y = 1550
-doctor.name = loc("Dr.Cornelius")
-doctor.x = 1300
-doctor.y = 1550
-guard1.name = loc("Bob")
-guard1.x = 3350
-guard1.y = 1800
-guard1.turn = false
-guard1.keepTurning = true
-guard2.name = loc("Sam")
-guard2.x = 3400
-guard2.y = 1800
-teamA.name = loc("PAoTH")
-teamA.color = tonumber("FF0000",16) -- red
-teamB.name = loc("Guards")
-teamB.color = tonumber("0033FF",16) -- blue
-teamC.name = loc("Hog Solo")
-teamC.color = tonumber("38D61C",16) -- green
-
--------------- LuaAPI EVENT HANDLERS ------------------
-function onGameInit()
- Seed = 35
- GameFlags = gfSolidLand + gfDisableWind
- TurnTime = 40000
- CaseFreq = 0
- MinesNum = 0
- Explosives = 0
- Delay = 5
- Map = "cosmos_map" -- custom map included in file
- Theme = "Nature"
- -- I had originally hero in PAoTH team and changed it, may reconsider though
- -- PAoTH
- AddTeam(teamC.name, teamC.color, "Bone", "Island", "HillBilly", "cm_birdy")
- hero.gear = AddHog(hero.name, 0, 100, "war_desertgrenadier1")
- AnimSetGearPosition(hero.gear, hero.x, hero.y)
- HogTurnLeft(hero.gear, true)
- AddTeam(teamA.name, teamA.color, "Bone", "Island", "HillBilly", "cm_birdy")
- director.gear = AddHog(director.name, 0, 100, "hair_yellow")
- AnimSetGearPosition(director.gear, director.x, director.y)
- doctor.gear = AddHog(doctor.name, 0, 100, "Glasses")
- AnimSetGearPosition(doctor.gear, doctor.x, doctor.y)
- -- Guards
- AddTeam(teamB.name, teamB.color, "Bone", "Island", "HillBilly", "cm_birdy")
- guard1.gear = AddHog(guard1.name, 1, 100, "policecap")
- AnimSetGearPosition(guard1.gear, guard1.x, guard1.y)
- guard2.gear = AddHog(guard2.name, 1, 100, "policecap")
- AnimSetGearPosition(guard2.gear, guard2.x, guard2.y)
-
- -- get the check point
- if tonumber(GetCampaignVar("CosmosCheckPoint")) then
- checkPointReached = tonumber(GetCampaignVar("CosmosCheckPoint"))
- end
- -- do checkpoint stuff needed before game starts
- if checkPointReached == 1 then
- -- Start of the game
- elseif checkPointReached == 2 then
- -- Hero on the column, just took space ship unnoticed
- AnimSetGearPosition(hero.gear, saucerX, saucerY)
- elseif checkPointReached == 3 then
- -- Hero near column, without space ship unnoticed
- elseif checkPointReached == 4 then
- -- Hero visited moon for fuels
- AnimSetGearPosition(hero.gear, 1110, 850)
- elseif checkPointReached == 5 then
- -- Hero has visited a planet, he has plenty of fuels and can change planet
- end
-
- AnimInit()
- AnimationSetup()
-end
-
-function onGameStart()
- -- wait for the first turn to start
- AnimWait(hero.gear, 3000)
-
- FollowGear(hero.gear)
- ShowMission(loc("A Space Adventure"), loc("Cosmos"), loc("Help Hog Solo to find all the parts of the anti-gravity device.")..
- "|"..loc("Travel to all the neighbor planets and collect all the pieces"), -amSkip, 0)
-
- -- do checkpoint stuff needed after game starts
- if checkPointReached == 1 then
- AddAnim(dialog01)
- AddAmmo(hero.gear, amGasBomb, 5)
- AddAmmo(hero.gear, amRope, 2)
- -- Added for dev/debug purposes, remove before release
- AddAmmo(hero.gear, amJetpack, 2)
- AddAmmo(guard1.gear, amDEagle, 2)
- AddAmmo(guard2.gear, amDEagle, 2)
- SpawnAmmoCrate(saucerX, saucerY, amJetpack)
- -- EVENT HANDLERS
- AddEvent(onHeroBeforeTreePosition, {hero.gear}, heroBeforeTreePosition, {hero.gear}, 0)
- AddEvent(onHeroAtSaucerPosition, {hero.gear}, heroAtSaucerPosition, {hero.gear}, 0)
- AddEvent(onHeroOutOfGuardSight, {hero.gear}, heroOutOfGuardSight, {hero.gear}, 0)
- elseif checkPointReached == 2 then
- AddAmmo(hero.gear, amJetpack, 1)
- AddAnim(dialog02)
- elseif checkPointReached == 3 then
- -- Hero near column, without space ship unnoticed
- elseif checkPointReached == 4 then
- -- Hero visited moon for fuels
- AddAnim(dialog05)
- elseif checkPointReached == 5 then
- -- Hero has visited a planet, he has plenty of fuels and can change planet
- end
- -- always check for landings
- if GetCampaignVar("Planet") ~= "moon" then
- AddEvent(onMoonLanding, {hero.gear}, moonLanding, {hero.gear}, 0)
- end
- if GetCampaignVar("Planet") ~= "desertPlanet" then
- AddEvent(onDesertPlanetLanding, {hero.gear}, desertPlanetLanding, {hero.gear}, 0)
- end
- if GetCampaignVar("Planet") ~= "fruitPlanet" then
- AddEvent(onFruitPlanetLanding, {hero.gear}, fruitPlanetLanding, {hero.gear}, 0)
- end
- if GetCampaignVar("Planet") ~= "icePlanet" then
- AddEvent(onIcePlanetLanding, {hero.gear}, icePlanetLanding, {hero.gear}, 0)
- end
-end
-
-function onGameTick()
- -- maybe alert this to avoid timeForGuard1ToTurnLeft overflow
- if timeForGuard1ToTurnLeft == 0 and guard1.keepTurning then
- guard1.turn = not guard1.turn
- HogTurnLeft(guard1.gear, guard1.turn)
- timeForGuard1ToTurnLeft = timeForGuard1ToTurn
- end
- timeForGuard1ToTurnLeft = timeForGuard1ToTurnLeft - 1
- AnimUnWait()
- if ShowAnimation() == false then
- return
- end
- ExecuteAfterAnimations()
- CheckEvents()
-end
-
-function onPrecise()
- if GameTime > 3000 then
- SetAnimSkip(true)
- end
-end
-
-function onAmmoStoreInit()
- SetAmmo(amJetpack, 0, 0, 0, 1)
-end
-
-function onNewTurn()
- if CurrentHedgehog == director.gear or CurrentHedgehog == doctor.gear then
- TurnTimeLeft = 0
- end
- if guard1.keepTurning then
- AnimSwitchHog(hero.gear)
- TurnTimeLeft = -1
- end
-end
-
--------------- EVENTS ------------------
-
-function onHeroBeforeTreePosition(gear)
- if GetX(gear) > 2444 then
- return true
- end
- return false
-end
-
-function onHeroAtSaucerPosition(gear)
- if GetX(gear) >= saucerX-32 and GetX(gear) <= saucerX+32 and GetY(gear) >= saucerY-32 and GetY(gear) <= saucerY+32 then
- saucerAcquired = true
- end
- if saucerAcquired and StoppedGear(gear) then
- return true
- end
- return false
-end
-
-function onHeroOutOfGuardSight(gear)
- if GetX(gear) < 3100 and GetY(gear) > saucerY-25 and StoppedGear(gear) and not guard1.keepTurning then
- return true
- end
- return false
-end
---
-function onMoonLanding(gear)
- if GetX(gear) > 1010 and GetX(gear) < 1220 and GetY(gear) < 1300 and StoppedGear(gear) then
- return true
- end
- return false
-end
-
-function onFruitPlanetLanding(gear)
- if GetX(gear) > 2240 and GetX(gear) < 2540 and GetY(gear) < 1100 and StoppedGear(gear) then
- return true
- end
- return false
-end
-
-function onDesertPlanetLanding(gear)
- if GetX(gear) > 3568 and GetX(gear) < 4052 and GetY(gear) < 500 and StoppedGear(gear) then
- return true
- end
- return false
-end
-
-function onIcePlanetLanding(gear)
- if GetX(gear) > 1330 and GetX(gear) < 1650 and GetY(gear) < 500 and StoppedGear(gear) then
- return true
- end
- return false
-end
-
--------------- OUTCOMES ------------------
-
-function heroBeforeTreePosition(gear)
- AnimSay(gear,loc("Now I have to climb the trees"), SAY_SAY, 4000)
- AnimCaption(hero.gear, loc("Use the rope to get to the crate"), 4000)
-end
-
-function heroAtSaucerPosition(gear)
- TurnTimeLeft = 0
- -- save check point
- SaveCampaignVar("CosmosCheckPoint", "2")
- AddAnim(dialog02)
- -- check if he was spotted by the guard
- if guard1.turn then
- guard1.keepTurning = false
- AddAnim(dialog03)
- end
-end
-
-function heroOutOfGuardSight(gear)
- guard1.keepTurning = true
- AddAnim(dialog04)
-end
-
-function moonLanding(gear)
- WriteLnToConsole("MOON LANDING, HOORAY!")
- AnimCaption(hero.gear,loc("Welcome to the moon!"))
- SaveCampaignVar("CosmosCheckPoint", "4")
- SaveCampaignVar("Planet", "moon")
- EndGame()
-end
-
-function fruitPlanetLanding(gear)
- if checkPointReached < 5 then
- AddAnim(dialog06)
- end
-end
-
-function desertPlanetLanding(gear)
- if checkPointReached < 5 then
- AddAnim(dialog06)
- end
-end
-
-function icePlanetLanding(gear)
- if checkPointReached < 5 then
- AddAnim(dialog06)
- end
-end
-
--------------- ANIMATIONS ------------------
-
-function Skipanim(anim)
- if goals[anim] ~= nil then
- ShowMission(unpack(goals[anim]))
- end
- if CurrentHedgehog ~= hero.gear and anim ~= dialog03 then
- AnimSwitchHog(hero.gear)
- elseif anim == dialog03 then
- startCombat()
- elseif anim == dialog05 or anim == dialog06 then
- EndGame()
- end
-end
-
-function AnimationSetup()
- -- DIALOG 01 - Start
- AddSkipFunction(dialog01, Skipanim, {dialog01})
- table.insert(dialog01, {func = AnimWait, args = {doctor.gear, 3000}})
- --table.insert(dialog01, {func = AnimWait, args = {hero.gear, 2500}, skipFunc = Skipanim, skipArgs = dialog01})
- table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("Near secret base 17 of PAoTH in the rural Hogland..."), 4000}})
- table.insert(dialog01, {func = AnimSay, args = {director.gear, loc("So Hog Solo, here we are..."), SAY_SAY, 2000}})
- table.insert(dialog01, {func = AnimSay, args = {director.gear, loc("Behind these trees on the East there is secret base 17"), SAY_SAY, 4000}})
- table.insert(dialog01, {func = AnimSay, args = {director.gear, loc("You have to continue alone from now on."), SAY_SAY, 3000}})
- table.insert(dialog01, {func = AnimSay, args = {director.gear, loc("Be careful, the future of Hogera is in your hands!"), SAY_SAY, 7200}})
- table.insert(dialog01, {func = AnimSay, args = {doctor.gear, loc("We'll use our communicators to contact you"), SAY_SAY, 2600}})
- table.insert(dialog01, {func = AnimSay, args = {doctor.gear, loc("In am also entrusting you with a rope and a sleep gas bomb"), SAY_SAY, 5000}})
- table.insert(dialog01, {func = AnimSay, args = {doctor.gear, loc("You may find them handy"), SAY_SAY, 2300}})
- table.insert(dialog01, {func = AnimSay, args = {hero.gear, loc("Thank you Dr.Cornelius"), SAY_SAY, 1600}})
- table.insert(dialog01, {func = AnimSay, args = {hero.gear, loc("I'll make good use of them"), SAY_SAY, 4500}})
- table.insert(dialog01, {func = AnimSay, args = {director.gear, loc("It would be wiser to steal the space ship while PAoTH guards are taking a brake!"), SAY_SAY, 7000}})
- table.insert(dialog01, {func = AnimSay, args = {director.gear, loc("Remember! Many will seek the anti-gravity device! Now go, hurry up!"), SAY_SAY, 4000}})
- table.insert(dialog01, {func = AnimSwitchHog, args = {hero.gear}})
- -- DIALOG 02 - Hero got the saucer
- AddSkipFunction(dialog02, Skipanim, {dialog02})
- table.insert(dialog02, {func = AnimWait, args = {hero.gear, 500}})
- table.insert(dialog02, {func = AnimCaption, args = {hero.gear, loc("CheckPoint reached!"), 4000}})
- table.insert(dialog02, {func = AnimSay, args = {hero.gear, loc("Got the saucer!"), SAY_SHOUT, 2000}})
- table.insert(dialog02, {func = AnimSay, args = {director.gear, loc("Nice!"), SAY_SHOUT, 1000}})
- table.insert(dialog02, {func = AnimSay, args = {director.gear, loc("Now use it and go to the moon PAoTH station to get more fuels!"), SAY_SHOUT, 5000}})
- table.insert(dialog02, {func = AnimGearWait, args = {hero.gear, 500}})
- -- DIALOG 03 - Hero got spotted by guard
- AddSkipFunction(dialog03, Skipanim, {dialog03})
- table.insert(dialog03, {func = AnimWait, args = {guard1.gear, 4000}})
- table.insert(dialog03, {func = AnimCaption, args = {guard1.gear, loc("Prepare to battle or flee!"), 4000}})
- table.insert(dialog03, {func = AnimSay, args = {guard1.gear, loc("Hey").." "..guard2.name.."! "..loc("Look, someone is stealing the saucer!"), SAY_SHOUT, 4000}})
- table.insert(dialog03, {func = AnimSay, args = {guard2.gear, loc("I'll get him!"), SAY_SAY, 4000}})
- table.insert(dialog03, {func = startCombat, args = {guard1.gear}})
- -- DIALOG 04 - Hero out of sight
- AddSkipFunction(dialog04, Skipanim, {dialog04})
- table.insert(dialog04, {func = AnimCaption, args = {guard1.gear, loc("You are out of danger, time to go to the moon!"), 4000}})
- table.insert(dialog04, {func = AnimSay, args = {guard1.gear, loc("I guess we lost him!"), SAY_SAY, 3000}})
- table.insert(dialog04, {func = AnimSay, args = {guard2.gear, loc("We should better report this and continue our watch!"), SAY_SAY, 5000}})
- table.insert(dialog04, {func = AnimSwitchHog, args = {hero.gear}})
- -- DIALOG 05 - Hero returned from moon without fuels
- AddSkipFunction(dialog05, Skipanim, {dialog05})
- table.insert(dialog05, {func = AnimSay, args = {hero.gear, loc("I guess I can't go far without fuels!"), SAY_THINK, 6000}})
- table.insert(dialog05, {func = AnimSay, args = {hero.gear, loc("Go to go back"), SAY_THINK, 2000}})
- table.insert(dialog05, {func = EndGame, args = {hero.gear}})
- -- DIALOG 06 - Landing on wrong planet or on earth if not enough fuels
- AddSkipFunction(dialog06, Skipanim, {dialog06})
- table.insert(dialog06, {func = AnimCaption, args = {hero.gear, loc("You have to try again!"), 5000}})
- table.insert(dialog06, {func = AnimSay, args = {hero.gear, loc("Hm... Now I run out of fuels..."), SAY_THINK, 3000}})
- table.insert(dialog06, {func = EndGame, args = {hero.gear}})
-end
-
-------------------- custom "animation" functions --------------------------
-
-function startCombat()
- -- use this so guard2 will gain control
- AnimSwitchHog(hero.gear)
- TurnTimeLeft = 0
-end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Missions/Campaign/A_Classic_Fairytale/CMakeLists.txt Mon Jul 01 23:23:22 2013 +0300
@@ -0,0 +1,9 @@
+file(GLOB Config *.ini)
+file(GLOB Missions *.lua)
+file(GLOB Packs *.hwp)
+
+install(FILES
+ ${Config}
+ ${Missions}
+ ${Packs}
+ DESTINATION "${SHAREPATH}Data/Missions/Campaign/A_Classic_Fairytale")
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Missions/Campaign/A_Classic_Fairytale/backstab.lua Mon Jul 01 23:23:22 2013 +0300
@@ -0,0 +1,1101 @@
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Animate.lua")
+
+-----------------------------Constants---------------------------------
+choiceAccepted = 1
+choiceRefused = 2
+choiceAttacked = 3
+
+choiceEliminate = 1
+choiceSpare = 2
+
+leaksNum = 1
+denseNum = 2
+waterNum = 3
+buffaloNum = 4
+chiefNum = 5
+girlNum = 6
+wiseNum = 7
+
+spyKillStage = 1
+platformStage = 2
+wave3Stage = 3
+
+tmpVar = 0
+
+nativeNames = {loc("Leaks A Lot"), loc("Dense Cloud"), loc("Fiery Water"),
+ loc("Raging Buffalo"), loc("Righteous Beard"), loc("Fell From Grace"),
+ loc("Wise Oak"), loc("Eagle Eye"), loc("Flaming Worm")}
+
+nativeHats = {"Rambo", "RobinHood", "pirate_jack", "zoo_Bunny", "IndianChief",
+ "tiara", "AkuAku", "None", "None"}
+
+nativePos = {{887, 329}, {1050, 288}, {1731, 707},
+ {830, 342}, {1001, 290}, {773, 340},
+ {953, 305}, {347, 648}, {314, 647}}
+
+nativeDir = {"Right", "Left", "Left",
+ "Right", "Left", "Right",
+ "Left", "Right", "Right"}
+
+cannibalNames = {loc("Brain Teaser"), loc("Bone Jackson"), loc("Gimme Bones"),
+ loc("Hedgibal Lecter"), loc("Bloodpie"), loc("Scalp Muncher"),
+ loc("Back Breaker"), loc("Dahmer"), loc("Meiwes"),
+ loc("Ear Sniffer"), loc("Regurgitator"), loc("Muriel")}
+
+cannibalPos = {{3607, 1472}, {3612, 1487}, {3646, 1502},
+ {3507, 195}, {3612, 1487}, {840, 1757},
+ {3056, 1231}, {2981, 1222}, {2785, 1258}}
+
+cannibalDir = {"Left", "Left", "Left",
+ "Left", "Right", "Right",
+ "Left", "Left", "Left"}
+
+cyborgPos = {1369, 574}
+cyborgPos2 = {1308, 148}
+
+deployedPos = {2522, 1365}
+-----------------------------Variables---------------------------------
+natives = {}
+nativeDead = {}
+nativeHidden = {}
+nativeRevived = {}
+nativesNum = 0
+
+cannibals = {}
+cannibalDead = {}
+cannibalHidden = {}
+
+speakerHog = nil
+spyHog = nil
+deployedHog = nil
+deployedDead = false
+
+cyborgHidden = false
+needToAct = 0
+
+m2Choice = 0
+m2DenseDead = 0
+m4DenseDead = 0
+m4BuffaloDead = 0
+m4WaterDead = 0
+m4ChiefDead = 0
+m4LeaksDead = 0
+
+needRevival = false
+gearr = nil
+startElimination = 0
+stage = 0
+choice = 0
+highJumped = false
+TurnsLeft = 0
+startNativesNum = 0
+
+startAnim = {}
+afterChoiceAnim = {}
+wave2Anim = {}
+wave2DeadAnim = {}
+wave3DeadAnim = {}
+
+vCircs = {}
+-----------------------------Animations--------------------------------
+function Wave2Reaction()
+ local i = 1
+ local gearr = nil
+ while nativeDead[i] == true do
+ i = i + 1
+ end
+ gearr = natives[i]
+ if nativeDead[denseNum] ~= true and band(GetState(natives[denseNum]), gstDrowning) == 0 then
+ AnimInsertStepNext({func = AnimCustomFunction, args = {dense, EmitDenseClouds, {"Left"}}})
+ AnimInsertStepNext({func = AnimTurn, args = {dense, "Left"}})
+ end
+ if nativeDead[buffaloNum] ~= true and band(GetState(natives[buffaloNum]), gstDrowning) == 0 then
+ AnimInsertStepNext({func = AnimSay, args = {natives[buffaloNum], loc("Let them have a taste of my fury!"), SAY_SHOUT, 6000}})
+ end
+ AnimInsertStepNext({func = AnimSay, args = {gearr, loc("There's more of them? When did they become so hungry?"), SAY_SHOUT, 8000}})
+end
+
+function EmitDenseClouds(dir)
+ local dif
+ if dir == "Left" then
+ dif = 10
+ else
+ dif = -10
+ end
+ AnimInsertStepNext({func = AnimVisualGear, args = {natives[denseNum], GetX(natives[denseNum]) + dif, GetY(natives[denseNum]) + dif, vgtSteam, 0, true}, swh = false})
+ AnimInsertStepNext({func = AnimVisualGear, args = {natives[denseNum], GetX(natives[denseNum]) + dif, GetY(natives[denseNum]) + dif, vgtSteam, 0, true}, swh = false})
+ AnimInsertStepNext({func = AnimVisualGear, args = {natives[denseNum], GetX(natives[denseNum]) + dif, GetY(natives[denseNum]) + dif, vgtSteam, 0, true}, swh = false})
+ AnimInsertStepNext({func = AnimWait, args = {natives[denseNum], 800}})
+ AnimInsertStepNext({func = AnimVisualGear, args = {natives[denseNum], GetX(natives[denseNum]) + dif, GetY(natives[denseNum]) + dif, vgtSteam, 0, true}, swh = false})
+ AnimInsertStepNext({func = AnimVisualGear, args = {natives[denseNum], GetX(natives[denseNum]) + dif, GetY(natives[denseNum]) + dif, vgtSteam, 0, true}, swh = false})
+ AnimInsertStepNext({func = AnimWait, args = {natives[denseNum], 800}})
+ AnimInsertStepNext({func = AnimVisualGear, args = {natives[denseNum], GetX(natives[denseNum]) + dif, GetY(natives[denseNum]) + dif, vgtSteam, 0, true}, swh = false})
+end
+
+function SaySafe()
+ local i = 1
+ while gearr == nil do
+ if nativeDead[i] ~= true and nativeHidden[i] ~= true then
+ gearr = natives[i]
+ end
+ i = i + 1
+ end
+ AnimInsertStepNext({func = AnimSay, args = {natives[wiseNum], loc("We are indeed."), SAY_SAY, 2500}})
+ AnimInsertStepNext({func = AnimSay, args = {gearr, loc("I think we are safe here."), SAY_SAY, 4000}})
+end
+
+function ReviveNatives()
+ for i = 1, 7 do
+ if nativeHidden[i] == true and nativeDead[i] ~= true then
+ RestoreHog(natives[i])
+ nativeHidden[i] = false
+ nativeRevived[i] = true
+ AnimInsertStepNext({func = AnimOutOfNowhere, args = {natives[i], unpack(nativePos[i])}})
+ end
+ end
+end
+
+function WonderAlive()
+ if nativeRevived[waterNum] == true then
+ AnimInsertStepNext({func = AnimSay, args = {natives[waterNum], loc("I'm...alive? How? Why?"), SAY_THINK, 3500}})
+ AnimInsertStepNext({func = AnimWait, args = {natives[waterNum], 800}})
+ AnimInsertStepNext({func = AnimTurn, args = {natives[waterNum], "Left"}})
+ AnimInsertStepNext({func = AnimWait, args = {natives[waterNum], 800}})
+ AnimInsertStepNext({func = AnimTurn, args = {natives[waterNum], "Right"}})
+ end
+ if nativeRevived[leaksNum] == true and nativeRevived[denseNum] == true then
+ AnimInsertStepNext({func = AnimSay, args = {natives[leaksNum], loc("But why would they help us?"), SAY_SAY, 4000}})
+ AnimInsertStepNext({func = AnimSay, args = {natives[leaksNum], loc("It must be the aliens!"), SAY_SAY, 3500}})
+ AnimInsertStepNext({func = AnimSay, args = {natives[girlNum], loc("You just appeared out of thin air!"), SAY_SAY, 5000}})
+ AnimInsertStepNext({func = AnimSay, args = {natives[leaksNum], loc("But...we died!"), SAY_SAY, 2500}})
+ AnimInsertStepNext({func = AnimSay, args = {natives[leaksNum], loc("This must be the caves!"), SAY_SAY, 3500}})
+ AnimInsertStepNext({func = AnimSay, args = {natives[denseNum], loc("Dude, where are we?"), SAY_SAY, 3000}})
+ AnimInsertStepNext({func = AnimWait, args = {natives[leaksNum], 800}})
+ AnimInsertStepNext({func = AnimTurn, args = {natives[leaksNum], "Right"}})
+ AnimInsertStepNext({func = AnimTurn, args = {natives[denseNum], "Left"}})
+ AnimInsertStepNext({func = AnimWait, args = {natives[leaksNum], 800}})
+ AnimInsertStepNext({func = AnimTurn, args = {natives[leaksNum], "Left"}})
+ AnimInsertStepNext({func = AnimTurn, args = {natives[denseNum], "Right"}})
+ AnimInsertStepNext({func = AnimWait, args = {natives[leaksNum], 800}})
+ AnimInsertStepNext({func = AnimTurn, args = {natives[leaksNum], "Right"}})
+ AnimInsertStepNext({func = AnimTurn, args = {natives[denseNum], "Left"}})
+ AnimInsertStepNext({func = AnimWait, args = {natives[leaksNum], 800}})
+ AnimInsertStepNext({func = AnimTurn, args = {natives[leaksNum], "Left"}})
+ AnimInsertStepNext({func = AnimTurn, args = {natives[denseNum], "Right"}})
+ AnimInsertStepNext({func = AnimCustomFunction, swh = false, args = {natives[leaksNum], CondNeedToTurn, {natives[leaksNum], natives[girlNum]}}})
+ if nativeDead[chiefNum] ~= true then
+ AnimInsertStepNext({func = AnimTurn, args = {natives[chiefNum], "Right"}})
+ end
+ elseif nativeRevived[leaksNum] == true then
+ AnimInsertStepNext({func = AnimSay, args = {natives[leaksNum], loc("Why would they do this?"), SAY_SAY, 6000}})
+ AnimInsertStepNext({func = AnimSay, args = {natives[wiseNum], loc("It must be the aliens' deed."), SAY_SAY, 5000}})
+ AnimInsertStepNext({func = AnimSay, args = {natives[wiseNum], loc("Do not laugh, inexperienced one, for he speaks the truth!"), SAY_SAY, 10000}})
+ AnimInsertStepNext({func = AnimSay, args = {natives[leaksNum], loc("Yeah, sure! I died. Hillarious!"), SAY_SAY, 6000}})
+ AnimInsertStepNext({func = AnimSay, args = {gearr, loc("You're...alive!? But we saw you die!"), SAY_SAY, 6000}})
+ AnimInsertStepNext({func = AnimSay, args = {gearr, loc("???"), SAY_SAY, 2000}})
+ AnimInsertStepNext({func = AnimSay, args = {natives[leaksNum], loc("Wow, what a dream!"), SAY_SAY, 3000}})
+ if nativeDead[chiefNum] ~= true then
+ AnimInsertStepNext({func = AnimTurn, args = {natives[chiefNum], "Right"}})
+ end
+ AnimInsertStepNext({func = AnimCustomFunction, swh = false, args = {natives[leaksNum], CondNeedToTurn, {natives[leaksNum], natives[wiseNum]}}})
+ AnimInsertStepNext({func = AnimCustomFunction, swh = false, args = {natives[leaksNum], CondNeedToTurn, {natives[leaksNum], gearr}}})
+ elseif nativeRevived[denseNum] == true then
+ AnimInsertStepNext({func = AnimSay, args = {natives[denseNum], loc("Dude, that's so cool!"), SAY_SAY, 3000}})
+ AnimInsertStepNext({func = AnimSay, args = {natives[wiseNum], loc("It must be the aliens' deed."), SAY_SAY, 5000}})
+ AnimInsertStepNext({func = AnimSay, args = {natives[denseNum], loc("But that's impossible!"), SAY_SAY, 3000}})
+ AnimInsertStepNext({func = AnimSay, args = {natives[wiseNum], loc("It was not a dream, unwise one!"), SAY_SAY, 5000}})
+ AnimInsertStepNext({func = AnimSay, args = {natives[denseNum], loc("Exactly, man! That was my dream."), SAY_SAY, 5000}})
+ AnimInsertStepNext({func = AnimSay, args = {gearr, loc("You're...alive!? But we saw you die!"), SAY_SAY, 6000}})
+ AnimInsertStepNext({func = AnimSay, args = {gearr, loc("???"), SAY_SAY, 2000}})
+ AnimInsertStepNext({func = AnimSay, args = {natives[denseNum], loc("Dude, wow! I just had the weirdest high!"), SAY_SAY, 6000}})
+ if nativeDead[chiefNum] ~= true then
+ AnimInsertStepNext({func = AnimTurn, args = {natives[chiefNum], "Right"}})
+ end
+ AnimInsertStepNext({func = AnimCustomFunction, swh = false, args = {natives[denseNum], CondNeedToTurn, {natives[denseNum], natives[wiseNum]}}})
+ AnimInsertStepNext({func = AnimCustomFunction, swh = false, args = {natives[denseNum], CondNeedToTurn, {natives[denseNum], gearr}}})
+ end
+end
+
+function ExplainAlive()
+ if needRevival == true and m4WaterDead == 1 then
+ RestoreCyborg()
+ AnimSetGearPosition(cyborg, unpack(cyborgPos))
+ AnimInsertStepNext({func = AnimCustomFunction, args = {water, HideCyborg, {}}})
+ AnimInsertStepNext({func = AnimSwitchHog, args = {water}})
+ AnimInsertStepNext({func = AnimSay, args = {cyborg, loc("The answer is...entertaintment. You'll see what I mean."), SAY_SAY, 8000}})
+ AnimInsertStepNext({func = AnimSay, args = {cyborg, loc("You're probably wondering why I bought you back..."), SAY_SAY, 8000}})
+ end
+end
+
+function SpyDebate()
+ if m2Choice == choiceAccepted then
+ spyHog = natives[denseNum]
+ AnimInsertStepNext({func = AnimSay, args = {natives[wiseNum], loc("What shall we do with the traitor?"), SAY_SAY, 6000}})
+ AnimInsertStepNext({func = SetHealth, swh = false, args = {natives[denseNum], 26}})
+ AnimInsertStepNext({func = AnimVisualGear, args = {natives[wiseNum], GetGearPosition(natives[denseNum]), vgtExplosion, 0, true}})
+ AnimInsertStepNext({func = AnimSay, args = {natives[wiseNum], loc("Here, let me help you!"), SAY_SAY, 3000}})
+ if nativeDead[chiefNum] == true then
+ AnimInsertStepNext({func = AnimSay, args = {natives[leaksNum], loc("I forgot that she's the daughter of the chief, too..."), SAY_THINK, 7000}})
+ AnimInsertStepNext({func = AnimSay, args = {natives[girlNum], loc("You killed my father, you monster!"), SAY_SAY, 5000}})
+ end
+ AnimInsertStepNext({func = AnimSay, args = {natives[denseNum], loc("Look, I had no choice!"), SAY_SAY, 3000}})
+ AnimInsertStepNext({func = AnimSay, args = {natives[leaksNum], loc("You have been giving us out to the enemy, haven't you!"), SAY_SAY, 7000}})
+ AnimInsertStepNext({func = AnimSay, args = {natives[leaksNum], loc("You're a pathetic liar!"), SAY_SAY, 3000}})
+ AnimInsertStepNext({func = AnimSay, args = {natives[leaksNum], loc("Interesting! Last time you said you killed a cannibal!"), SAY_SAY, 7000}})
+ AnimInsertStepNext({func = AnimSay, args = {natives[denseNum], loc("I told you, I just found them."), SAY_SAY, 4500}})
+ AnimInsertStepNext({func = AnimCustomFunction, args = {natives[denseNum], EmitDenseClouds, {"Left"}}})
+ AnimInsertStepNext({func = AnimSay, args = {natives[leaksNum], loc("Where did you get the weapons in the forest, Dense Cloud?"), SAY_SAY, 8000}})
+ AnimInsertStepNext({func = AnimSay, args = {natives[leaksNum], loc("Not now, Fiery Water!"), SAY_SAY, 3000}})
+ else
+ spyHog = natives[waterNum]
+ AnimInsertStepNext({func = AnimSay, args = {natives[wiseNum], loc("What shall we do with the traitor?"), SAY_SAY, 5000}})
+ AnimInsertStepNext({func = SetHealth, swh = false, args = {natives[waterNum], 26}})
+ AnimInsertStepNext({func = AnimVisualGear, args = {natives[wiseNum], nativePos[denseNum][1] + 50, nativePos[denseNum][2], vgtExplosion, 0, true}})
+ AnimInsertStepNext({func = AnimSay, args = {natives[girlNum], loc("I can't believe what I'm hearing!"), SAY_SAY, 5500}})
+ AnimInsertStepNext({func = AnimSay, args = {natives[waterNum], loc("You know what? I don't even regret anything!"), SAY_SAY, 7000}})
+ AnimInsertStepNext({func = AnimSay, args = {natives[girlNum], loc("In fact, you are the only one that's been acting strangely."), SAY_SAY, 8000}})
+ AnimInsertStepNext({func = AnimSay, args = {natives[waterNum], loc("Are you accusing me of something?"), SAY_SAY, 3500}})
+ AnimInsertStepNext({func = AnimSay, args = {natives[leaksNum], loc("Seems like every time you take a \"walk\", the enemy find us!"), SAY_SAY, 8000}})
+ AnimInsertStepNext({func = AnimSay, args = {natives[waterNum], loc("You know...taking a stroll."), SAY_SAY, 3500}})
+ AnimInsertStepNext({func = AnimSay, args = {natives[leaksNum], loc("Where have you been?!"), SAY_SAY, 3000}})
+ end
+ if nativeRevived[waterNum] == true then
+ AnimInsertStepNext({func = AnimSay, args = {natives[waterNum], loc("You won't believe what happened to me!"), SAY_SAY, 5500}})
+ end
+ AnimInsertStepNext({func = AnimSay, args = {natives[waterNum], loc("Hey, guys!"), SAY_SAY, 2000}})
+ AnimInsertStepNext({func = AnimMove, args = {natives[waterNum], "Left", nativePos[denseNum][1] + 50, nativePos[denseNum][2]}})
+ AnimInsertStepNext({func = AnimJump, args = {natives[waterNum], "back"}})
+ AnimInsertStepNext({func = AnimTurn, args = {natives[waterNum], "Right"}})
+ AnimInsertStepNext({func = AnimMove, args = {natives[waterNum], "Left", 1228, 412}})
+ AnimInsertStepNext({func = AnimJump, args = {natives[waterNum], "long"}})
+ AnimInsertStepNext({func = AnimJump, args = {natives[waterNum], "long"}})
+ AnimInsertStepNext({func = AnimJump, args = {natives[waterNum], "long"}})
+ AnimInsertStepNext({func = AnimTurn, args = {natives[waterNum], "Left"}})
+ AnimInsertStepNext({func = AnimSay, args = {natives[wiseNum], loc("There must be a spy among us!"), SAY_SAY, 4000}})
+ AnimInsertStepNext({func = AnimSay, args = {natives[girlNum], loc("We made sure noone followed us!"), SAY_SAY, 4000}})
+ AnimInsertStepNext({func = AnimSay, args = {natives[leaksNum], loc("What? Here? How did they find us?!"), SAY_SAY, 5000}})
+end
+
+function AnimationSetup()
+ table.insert(startAnim, {func = AnimWait, swh = false, args = {natives[leaksNum], 3000}})
+ table.insert(startAnim, {func = AnimCustomFunction, swh = false, args = {natives[leaksNum], SaySafe, {}}})
+ if needRevival == true then
+ table.insert(startAnim, {func = AnimCustomFunction, swh = false, args = {cyborg, ReviveNatives, {}}})
+ table.insert(startAnim, {func = AnimCustomFunction, swh = false, args = {natives[leaksNum], WonderAlive, {}}})
+ table.insert(startAnim, {func = AnimCustomFunction, swh = false, args = {cyborg, ExplainAlive, {}}})
+ end
+ table.insert(startAnim, {func = AnimCustomFunction, swh = false, args = {natives[leaksNum], RestoreWave, {1}}})
+ table.insert(startAnim, {func = AnimOutOfNowhere, args = {cannibals[1], unpack(cannibalPos[1])}})
+ table.insert(startAnim, {func = AnimOutOfNowhere, args = {cannibals[2], unpack(cannibalPos[2])}})
+ table.insert(startAnim, {func = AnimOutOfNowhere, args = {cannibals[3], unpack(cannibalPos[3])}})
+ table.insert(startAnim, {func = AnimWait, args = {natives[leaksNum], 1000}})
+ table.insert(startAnim, {func = AnimCustomFunction, swh = false, args = {natives[leaksNum], SpyDebate, {}}})
+ AddSkipFunction(startAnim, SkipStartAnim, {})
+end
+
+function SetupWave2Anim()
+ for i = 7, 1, -1 do
+ if nativeDead[i] ~= true then
+ speakerHog = natives[i]
+ end
+ end
+ table.insert(wave2Anim, {func = AnimOutOfNowhere, args = {cannibals[4], unpack(cannibalPos[4])}})
+ table.insert(wave2Anim, {func = AnimOutOfNowhere, args = {cannibals[5], unpack(cannibalPos[5])}})
+ table.insert(wave2Anim, {func = AnimOutOfNowhere, args = {cannibals[6], unpack(cannibalPos[6])}})
+ table.insert(wave2Anim, {func = AnimSay, args = {speakerHog, loc("Look out! There's more of them!"), SAY_SHOUT, 5000}})
+ AddSkipFunction(wave2Anim, SkipWave2Anim, {})
+end
+
+function PutCircles()
+ if circlesPut then
+ return
+ end
+ vCircs[1] = AddVisualGear(0,0,vgtCircle,0,true)
+ vCircs[2] = AddVisualGear(0,0,vgtCircle,0,true)
+ vCircs[3] = AddVisualGear(0,0,vgtCircle,0,true)
+ SetVisualGearValues(vCircs[1], cannibalPos[7][1], cannibalPos[7][2], 100, 255, 1, 10, 0, 120, 3, 0xff00ffff)
+ SetVisualGearValues(vCircs[2], cannibalPos[8][1], cannibalPos[8][2], 100, 255, 1, 10, 0, 120, 3, 0xff00ffff)
+ SetVisualGearValues(vCircs[3], cannibalPos[9][1], cannibalPos[9][2], 100, 255, 1, 10, 0, 120, 3, 0xff00ffff)
+ circlesPut = true
+end
+
+function SetupWave2DeadAnim()
+ for i = 7, 1, -1 do
+ if nativeDead[i] ~= true then
+ deployedHog = natives[i]
+ end
+ end
+ if nativeDead[wiseNum] ~= true and band(GetState(natives[wiseNum]), gstDrowning) == 0 then
+ if nativesNum > 1 then
+ table.insert(wave2DeadAnim, {func = AnimWait, args = {natives[wiseNum], 1500}})
+ table.insert(wave2DeadAnim, {func = AnimSay, args = {natives[wiseNum], loc("What a strange feeling!"), SAY_THINK, 3000}})
+ table.insert(wave2DeadAnim, {func = AnimSay, args = {natives[wiseNum], loc("I need to warn the others."), SAY_THINK, 3000}})
+ table.insert(wave2DeadAnim, {func = AnimSay, args = {natives[wiseNum], loc("If only I had a way..."), SAY_THINK, 3000}})
+ table.insert(wave2DeadAnim, {func = AnimSay, args = {natives[wiseNum], loc("Oh, silly me! I forgot that I'm the shaman."), SAY_THINK, 6000}})
+ table.insert(wave2DeadAnim, {func = AnimCustomFunction, args = {natives[wiseNum], TeleportNatives, {}}})
+ table.insert(wave2DeadAnim, {func = AnimCustomFunction, args = {natives[wiseNum], TurnNatives, {natives[wiseNum]}}})
+ table.insert(wave2DeadAnim, {func = AnimCustomFunction, args = {natives[wiseNum], CondNeedToTurn, {natives[wiseNum], deployedHog}}})
+ table.insert(wave2DeadAnim, {func = AnimSay, args = {natives[wiseNum], loc("I sense another wave of cannibals heading our way!"), SAY_SAY, 6500}})
+ table.insert(wave2DeadAnim, {func = AnimSay, args = {natives[wiseNum], loc("I feel something...a place! They will arrive near the circles!"), SAY_SAY, 7500}})
+ table.insert(wave2DeadAnim, {func = AnimCustomFunction, args = {natives[wiseNum], PutCircles, {}}})
+ table.insert(wave2DeadAnim, {func = AnimFollowGear, swh = false, args = {vCircs[1]}})
+ table.insert(wave2DeadAnim, {func = AnimWait, args = {natives[wiseNum], 1500}})
+ table.insert(wave2DeadAnim, {func = AnimSay, args = {natives[wiseNum], loc("We need to prevent their arrival!"), SAY_SAY, 4500}})
+ table.insert(wave2DeadAnim, {func = AnimSay, args = {natives[wiseNum], loc("Go, quick!"), SAY_SAY, 2500}})
+ table.insert(wave2DeadAnim, {func = AnimCustomFunction, args = {natives[wiseNum], DeployHog, {}}})
+ table.insert(wave2DeadAnim, {func = AnimCustomFunction, args = {natives[wiseNum], RestoreCyborg, {}}})
+ table.insert(wave2DeadAnim, {func = AnimOutOfNowhere, swh = false, args = {cyborg, cyborgPos2[1], cyborgPos2[2]}})
+ table.insert(wave2DeadAnim, {func = AnimTurn, args = {cyborg, "Left"}})
+ table.insert(wave2DeadAnim, {func = AnimCustomFunction, args = {cyborg, IsolateNatives, {}}})
+ table.insert(wave2DeadAnim, {func = AnimCustomFunction, args = {cyborg, PutCGI, {}}})
+ table.insert(wave2DeadAnim, {func = AnimSay, args = {cyborg, loc("I want to see how it handles this!"), SAY_SAY, 6000}})
+ table.insert(wave2DeadAnim, {func = AnimSwitchHog, args = {deployedHog}})
+ table.insert(wave2DeadAnim, {func = AnimDisappear, args = {cyborg, 0, 0}})
+-- table.insert(wave2DeadAnim, {func = AnimCustomFunction, args = {cyborg, DeployHog, {}}})
+ table.insert(wave2DeadAnim, {func = AnimCustomFunction, swh = false, args = {cyborg, HideCyborg, {}}})
+ else
+ table.insert(wave2DeadAnim, {func = AnimWait, args = {natives[wiseNum], 1500}})
+ table.insert(wave2DeadAnim, {func = AnimSay, args = {natives[wiseNum], loc("What a strange feeling!"), SAY_THINK, 3000}})
+ table.insert(wave2DeadAnim, {func = AnimSay, args = {natives[wiseNum], loc("I sense another wave of cannibals heading my way!"), SAY_THINK, 6500}})
+ table.insert(wave2DeadAnim, {func = AnimSay, args = {natives[wiseNum], loc("I feel something...a place! They will arrive near the circles!"), SAY_SAY, 7500}})
+ table.insert(wave2DeadAnim, {func = AnimCustomFunction, args = {natives[wiseNum], PutCircles, {}}})
+ table.insert(wave2DeadAnim, {func = AnimFollowGear, swh = false, args = {vCircs[1]}})
+ table.insert(wave2DeadAnim, {func = AnimSay, args = {natives[wiseNum], loc("I need to prevent their arrival!"), SAY_THINK, 4500}})
+ table.insert(wave2DeadAnim, {func = AnimSay, args = {natives[wiseNum], loc("If only I had a way..."), SAY_THINK, 3000}})
+ table.insert(wave2DeadAnim, {func = AnimSay, args = {natives[wiseNum], loc("Oh, silly me! I forgot that I'm the shaman."), SAY_THINK, 6000}})
+ end
+ else
+ table.insert(wave2DeadAnim, {func = AnimWait, args = {cyborg, 1500}})
+ table.insert(wave2DeadAnim, {func = AnimCustomFunction, swh = false, args = {cyborg, RestoreCyborg, {}}})
+ table.insert(wave2DeadAnim, {func = AnimOutOfNowhere, args = {cyborg, cyborgPos2[1], cyborgPos2[2]}})
+ table.insert(wave2DeadAnim, {func = AnimTurn, args = {cyborg, "Left"}})
+ table.insert(wave2DeadAnim, {func = AnimCustomFunction, args = {cyborg, TeleportNatives, {}}})
+ table.insert(wave2DeadAnim, {func = AnimCustomFunction, args = {cyborg, TurnNatives, {cyborg}}})
+ table.insert(wave2DeadAnim, {func = AnimSay, args = {cyborg, loc("Oh, my! This is even more entertaining than I've expected!"), SAY_SAY, 7500}})
+ table.insert(wave2DeadAnim, {func = AnimSay, args = {cyborg, loc("You might want to find a way to instantly kill arriving cannibals!"), SAY_SAY, 8000}})
+ table.insert(wave2DeadAnim, {func = AnimSay, args = {cyborg, loc("I believe there's more of them."), SAY_SAY, 4000}})
+ table.insert(wave2DeadAnim, {func = AnimSay, args = {cyborg, loc("I marked the place of their arrival. You're welcome!"), SAY_SAY, 6000}})
+ table.insert(wave2DeadAnim, {func = AnimCustomFunction, args = {natives[wiseNum], PutCircles, {}}})
+ table.insert(wave2DeadAnim, {func = AnimFollowGear, swh = false, args = {vCircs[1]}})
+ table.insert(wave2DeadAnim, {func = AnimCustomFunction, args = {deployedHog, DeployHog, {}}})
+ if nativesNum > 1 then
+-- table.insert(wave2DeadAnim, {func = AnimCustomFunction, args = {natives[wiseNum], RestoreCyborg, {}}})
+-- table.insert(wave2DeadAnim, {func = AnimOutOfNowhere, swh = false, args = {cyborg, cyborgPos2[1], cyborgPos2[2]}})
+-- table.insert(wave2DeadAnim, {func = AnimTurn, args = {cyborg, "Left"}})
+ table.insert(wave2DeadAnim, {func = AnimCustomFunction, args = {cyborg, IsolateNatives, {}}})
+ table.insert(wave2DeadAnim, {func = AnimCustomFunction, args = {cyborg, PutCGI, {}}})
+ table.insert(wave2DeadAnim, {func = AnimSay, args = {cyborg, loc("I want to see how it handles this!"), SAY_SAY, 6000}})
+ end
+ table.insert(wave2DeadAnim, {func = AnimSwitchHog, args = {deployedHog}})
+ table.insert(wave2DeadAnim, {func = AnimDisappear, swh = false, args = {cyborg, 0, 0}})
+ table.insert(wave2DeadAnim, {func = AnimCustomFunction, swh = false, args = {cyborg, HideCyborg, {}}})
+ end
+ AddSkipFunction(wave2DeadAnim, SkipWave2DeadAnim, {})
+end
+
+function IsolateNatives()
+ PlaceGirder(710, 299, 6)
+ PlaceGirder(690, 299, 6)
+ PlaceGirder(761, 209, 4)
+ PlaceGirder(921, 209, 4)
+ PlaceGirder(1081, 209, 4)
+ PlaceGirder(761, 189, 4)
+ PlaceGirder(921, 189, 4)
+ PlaceGirder(1081, 189, 4)
+ PlaceGirder(761, 169, 4)
+ PlaceGirder(921, 169, 4)
+ PlaceGirder(1081, 169, 4)
+ PlaceGirder(761, 149, 4)
+ PlaceGirder(921, 149, 4)
+ PlaceGirder(1081, 149, 4)
+ PlaceGirder(761, 129, 4)
+ PlaceGirder(921, 129, 4)
+ PlaceGirder(1081, 129, 4)
+ PlaceGirder(1120, 261, 2)
+ PlaceGirder(1140, 261, 2)
+ PlaceGirder(1160, 261, 2)
+ AddAmmo(deployedHog, amDEagle, 0)
+ AddAmmo(deployedHog, amFirePunch, 0)
+end
+
+function PutCGI()
+ AddVisualGear(710, 299, vgtExplosion, 0, true)
+ AddVisualGear(690, 299, vgtExplosion, 0, true)
+ AddVisualGear(761, 209, vgtExplosion, 0, true)
+ AddVisualGear(921, 209, vgtExplosion, 0, true)
+ AddVisualGear(1081, 209, vgtExplosion, 0, true)
+ AddVisualGear(761, 189, vgtExplosion, 0, true)
+ AddVisualGear(921, 189, vgtExplosion, 0, true)
+ AddVisualGear(1081, 189, vgtExplosion, 0, true)
+ AddVisualGear(761, 169, vgtExplosion, 0, true)
+ AddVisualGear(921, 169, vgtExplosion, 0, true)
+ AddVisualGear(1081, 169, vgtExplosion, 0, true)
+ AddVisualGear(761, 149, vgtExplosion, 0, true)
+ AddVisualGear(921, 149, vgtExplosion, 0, true)
+ AddVisualGear(1081, 149, vgtExplosion, 0, true)
+ AddVisualGear(761, 129, vgtExplosion, 0, true)
+ AddVisualGear(921, 129, vgtExplosion, 0, true)
+ AddVisualGear(1081, 129, vgtExplosion, 0, true)
+ AddVisualGear(1120, 261, vgtExplosion, 0, true)
+ AddVisualGear(1140, 261, vgtExplosion, 0, true)
+ AddVisualGear(1160, 261, vgtExplosion, 0, true)
+end
+
+function TeleportNatives()
+ nativePos[waterNum] = {1100, 288}
+ for i = 1, 7 do
+ if nativeDead[i] ~= true then
+ AnimTeleportGear(natives[i], unpack(nativePos[i]))
+ end
+ end
+end
+
+function TurnNatives(hog)
+ for i = 1, 7 do
+ if nativeDead[i] == false then
+ if GetX(natives[i]) < GetX(hog) then
+ AnimTurn(natives[i], "Right")
+ else
+ AnimTurn(natives[i], "Left")
+ end
+ end
+ end
+end
+
+function DeployHog()
+ AnimSwitchHog(deployedHog)
+ AnimTeleportGear(deployedHog, unpack(deployedPos))
+ if deployedHog ~= natives[wiseNum] then
+ AnimSay(deployedHog, loc("Why me?!"), SAY_THINK, 2000)
+ end
+end
+
+function SetupAfterChoiceAnim()
+ for i = 7, 1, -1 do
+ if nativeDead[i] ~= true then
+ if natives[i] ~= spyHog then
+ speakerHog = natives[i]
+ end
+ end
+ end
+ if choice == choiceEliminate then
+ table.insert(afterChoiceAnim, {func = AnimWait, args = {speakerHog, 1500}})
+ table.insert(afterChoiceAnim, {func = AnimSay, args = {speakerHog, loc("He won't be selling us out anymore!"), SAY_SAY, 6000}})
+ if nativeDead[girlNum] ~= true and m4ChiefDead == 1 then
+ table.insert(afterChoiceAnim, {func = AnimSay, args = {natives[girlNum], loc("That's for my father!"), SAY_SAY, 3500}})
+ end
+ table.insert(afterChoiceAnim, {func = AnimSay, args = {speakerHog, loc("Let's show those cannibals what we're made of!"), SAY_SAY, 7000}})
+ else
+ table.insert(afterChoiceAnim, {func = AnimCustomFunction, swh = false, args = {natives[leaksNum], CondNeedToTurn, {speakerHog, spyHog}}})
+ table.insert(afterChoiceAnim, {func = AnimSay, args = {speakerHog, loc("We'll spare your life for now!"), SAY_SAY, 4500}})
+ table.insert(afterChoiceAnim, {func = AnimSay, args = {spyHog, loc("May the spirits aid you in all your quests!"), SAY_SAY, 7000}})
+ table.insert(afterChoiceAnim, {func = AnimSay, args = {speakerHog, loc("I just don't want to sink to your level."), SAY_SAY, 6000}})
+ table.insert(afterChoiceAnim, {func = AnimSay, args = {speakerHog, loc("Let's show those cannibals what we're made of!"), SAY_SAY, 7000}})
+ end
+ table.insert(afterChoiceAnim, {func = AnimSay, args = {natives[8], loc("Let us help, too!"), SAY_SAY, 3000}})
+ table.insert(afterChoiceAnim, {func = AnimTurn, args = {speakerHog, "Left", SAY_SAY, 7000}})
+ table.insert(afterChoiceAnim, {func = AnimSay, args = {speakerHog, loc("No. You and the rest of the tribe are safer there!"), SAY_SAY, 7000}})
+ AddSkipFunction(afterChoiceAnim, SkipAfterChoiceAnim, {})
+end
+
+function SetupHogDeadAnim(gear)
+ hogDeadAnim = {}
+ if nativesNum == 0 then
+ return
+ end
+ local hogDeadStrings = {loc("They killed ") .. gear .. loc("! You bastards!"),
+ gear .. loc("! Why?!"),
+ loc("That was just mean!"),
+ loc("Oh no, not ") .. gear .. "!",
+ loc("Why ") .. gear .. loc("? Why?"),
+ loc("What has ") .. gear .. loc(" ever done to you?!")}
+ table.insert(hogDeadAnim, {func = AnimSay, args = {CurrentHedgehog, hogDeadStrings[7 - nativesNum], SAY_SHOUT, 4000}})
+end
+
+function AfterHogDeadAnim()
+ freshDead = nil
+ TurnTimeLeft = TurnTime
+end
+
+--------------------------Anim skip functions--------------------------
+
+function AfterAfterChoiceAnim()
+ stage = 0
+ AddEvent(CheckWaveDead, {1}, DoWaveDead, {1}, 0)
+ AddAmmo(speakerHog, amSwitch, 100)
+ SetGearMessage(speakerHog, 0)
+ SetState(speakerHog, 0)
+ TurnTimeLeft = -1
+ ShowMission(loc("Backstab"), loc("The food bites back"), loc("Defeat the cannibals"), 1, 4000)
+ SpawnCrates()
+end
+
+function SkipAfterChoiceAnim()
+ SetGearMessage(CurrentHedgehog, 0)
+ AnimSwitchHog(speakerHog)
+end
+
+function AfterWave2Anim()
+ AddEvent(CheckWaveDead, {2}, DoWaveDead, {2}, 0)
+ SetGearMessage(CurrentHedgehog, 0)
+ SetState(CurrentHedgehog, 0)
+ SpawnCrates()
+ TurnTimeLeft = TurnTime
+end
+
+function SkipWave2DeadAnim()
+ TeleportNatives()
+ IsolateNatives()
+ DeployHog()
+ HideCyborg()
+ PutCircles()
+end
+
+function SpawnPlatformCrates()
+ SpawnAmmoCrate(2494, 1262, amMine)
+ SpawnAmmoCrate(2574, 1279, amSMine)
+ SpawnAmmoCrate(2575, 1267, amMine)
+ SpawnAmmoCrate(2617, 1259, amSMine)
+ SpawnUtilityCrate(2579, 1254, amMine)
+ SpawnUtilityCrate(2478, 1243, amMine)
+end
+
+function AfterWave2DeadAnim()
+ TurnsLeft = 7
+ stage = platformStage
+ SpawnPlatformCrates()
+ SetGearMessage(CurrentHedgehog, 0)
+ AddEvent(CheckTurnsOver, {}, DoTurnsOver, {3}, 0)
+ AddEvent(CheckWaveDead, {3}, DoWaveDead, {3}, 0)
+ AddEvent(CheckDeployedDead, {}, DoDeployedDead, {}, 0)
+ TurnTimeLeft = 0
+ ShowMission(loc("Backstab"), loc("Drills"), loc("You have 7 turns until the next wave arrives.|Make sure the arriving cannibals are greeted appropriately!|If the hog dies, the cause is lost.|Hint: you might want to use some mines..."), 1, 12000)
+end
+
+function DoTurnsOver()
+ stage = wave3Stage
+ RestoreWave(3)
+end
+
+function SkipWave2Anim()
+ AnimSwitchHog(speakerHog)
+end
+
+function SkipStartAnim()
+ AnimSetGearPosition(natives[waterNum], nativePos[denseNum][1] + 50, nativePos[denseNum][2])
+ RestoreWave(1)
+ ReviveNatives()
+ SetGearMessage(CurrentHedgehog, 0)
+ SetState(CurrentHedgehog, 0)
+ if m2Choice == choiceAccepted then
+ spyHog = natives[denseNum]
+ else
+ spyHog = natives[waterNum]
+ end
+ SetHealth(spyHog, 26)
+end
+
+function AfterStartAnim()
+ AnimSwitchHog(natives[leaksNum])
+ TurnTimeLeft = 0
+ stage = spyKillStage
+ AddEvent(CheckChoice, {}, DoChoice, {}, 0)
+ AddEvent(CheckKilledOther, {}, DoKilledOther, {}, 0)
+ AddEvent(CheckChoiceRefuse, {}, DoChoiceRefuse, {}, 0)
+ ShowMission(loc("Backstab"), loc("Judas"), loc("Kill the traitor...or spare his life!|Kill him or press [Precise]!"), 1, 8000)
+end
+
+-----------------------------Events------------------------------------
+function CheckTurnsOver()
+ return TurnsLeft == 0
+end
+
+function CheckDeployedDead()
+ return deployedDead
+end
+
+function DoDeployedDead()
+ ShowMission(loc("Backstab"), loc("Brutus"), loc("You have failed to save the tribe!"), 0, 6000)
+ ParseCommand("teamgone " .. loc("Natives"))
+ ParseCommand("teamgone " .. loc("Tribe"))
+ ParseCommand("teamgone " .. loc("011101001"))
+ TurnTimeLeft = 0
+end
+
+function CheckChoice()
+ return choice ~= 0 and tmpVar == 0
+end
+
+function CheckDeaths()
+ for i = 1, 7 do
+ if natives[i] ~= spyHog and band(GetState(natives[i]), gstAttacked) ~= 0 then
+ return true
+ end
+ end
+ return false
+end
+
+function DoChoice()
+ RemoveEventFunc(CheckChoiceRefuse)
+ SetGearMessage(CurrentHedgehog, 0)
+ SetupAfterChoiceAnim()
+ AddAnim(afterChoiceAnim)
+ AddFunction({func = AfterAfterChoiceAnim, args = {}})
+end
+
+function CheckChoiceRefuse()
+ return highJumped == true and StoppedGear(CurrentHedgehog)
+end
+
+function DoChoiceRefuse()
+ choice = choiceSpare
+end
+
+function CheckKilledOther()
+ if stage ~= spyKillStage then
+ return false
+ end
+ return (nativesNum < startNativesNum and choice ~= choiceEliminate) or
+ (nativesNum < startNativesNum - 1 and choice == choiceEliminate)
+end
+
+function DoKilledOther()
+ ShowMission(loc("Backstab"), loc("Brutus"), loc("You have killed an innocent hedgehog!"), 0, 6000)
+ ParseCommand("teamgone " .. loc("Natives"))
+ ParseCommand("teamgone " .. loc("Tribe"))
+ TurnTimeLeft = 0
+end
+
+function CheckWaveDead(index)
+ for i = (index - 1) * 3 + 1, index * 3 do
+ if cannibalDead[i] ~= true or CurrentHedgehog == cannibals[i] then
+ return false
+ end
+ end
+ return true
+end
+
+function DoWaveDead(index)
+ TurnTimeLeft = 0
+ needToAct = index
+end
+
+function AddWave3DeadAnim()
+ AnimSwitchHog(deployedHog)
+ AnimWait(deployedHog, 1)
+ AddFunction({func = HideNatives, args = {}})
+ AddFunction({func = SetupWave3DeadAnim, args = {}})
+ AddFunction({func = AddAnim, args = {wave3DeadAnim}})
+ AddFunction({func = AddFunction, args = {{func = AfterWave3DeadAnim, args = {}}}})
+end
+
+function HideNatives()
+ for i = 1, 9 do
+ if nativeDead[i] ~= true and natives[i] ~= deployedHog then
+ if nativeHidden[i] ~= true then
+ HideHog(natives[i])
+ nativeHidden[i] = true
+ end
+ end
+ end
+end
+
+function SetupWave3DeadAnim()
+ table.insert(wave3DeadAnim, {func = AnimTurn, args = {deployedHog, "Left"}})
+ table.insert(wave3DeadAnim, {func = AnimSay, args = {deployedHog, loc("That ought to show them!"), SAY_SAY, 4000}})
+ table.insert(wave3DeadAnim, {func = AnimSay, args = {deployedHog, loc("Guys, do you think there's more of them?"), SAY_SHOUT, 7000}})
+ table.insert(wave3DeadAnim, {func = AnimVisualGear, args = {deployedHog, unpack(nativePos[wiseNum]), vgtFeather, 0, true, true}})
+ table.insert(wave3DeadAnim, {func = AnimWait, args = {deployedHog, 1000}})
+ table.insert(wave3DeadAnim, {func = AnimSay, args = {deployedHog, loc("Where are they?!"), SAY_THINK, 3000}})
+ table.insert(wave3DeadAnim, {func = AnimCustomFunction, args = {deployedHog, RestoreCyborg, {}}})
+ table.insert(wave3DeadAnim, {func = AnimOutOfNowhere, args = {cyborg, 4040, 782}})
+ table.insert(wave3DeadAnim, {func = AnimSay, args = {cyborg, loc("These primitive people are so funny!"), SAY_THINK, 6500}})
+ table.insert(wave3DeadAnim, {func = AnimMove, args = {cyborg, "Right", 4060, 0}})
+ table.insert(wave3DeadAnim, {func = AnimSwitchHog, args = {deployedHog}})
+ table.insert(wave3DeadAnim, {func = AnimWait, args = {deployedHog, 1}})
+ table.insert(wave3DeadAnim, {func = AnimCustomFunction, args = {deployedHog, HideCyborg, {}}})
+ table.insert(wave3DeadAnim, {func = AnimSay, args = {deployedHog, loc("I need to find the others!"), SAY_THINK, 4500}})
+ table.insert(wave3DeadAnim, {func = AnimSay, args = {deployedHog, loc("I have to follow that alien."), SAY_THINK, 4500}})
+end
+
+function SkipWave3DeadAnim()
+ AnimSwitchHog(deployedHog)
+end
+
+function AfterWave3DeadAnim()
+ if nativeDead[leaksNum] == true then
+ SaveCampaignVar("M5LeaksDead", "1")
+ else
+ SaveCampaignVar("M5LeaksDead", "0")
+ end
+ if nativeDead[denseNum] == true then
+ SaveCampaignVar("M5DenseDead", "1")
+ else
+ SaveCampaignVar("M5DenseDead", "0")
+ end
+ if nativeDead[waterNum] == true then
+ SaveCampaignVar("M5WaterDead", "1")
+ else
+ SaveCampaignVar("M5WaterDead", "0")
+ end
+ if nativeDead[buffaloNum] == true then
+ SaveCampaignVar("M5BuffaloDead", "1")
+ else
+ SaveCampaignVar("M5BuffaloDead", "0")
+ end
+ if nativeDead[girlNum] == true then
+ SaveCampaignVar("M5GirlDead", "1")
+ else
+ SaveCampaignVar("M5GirlDead", "0")
+ end
+ if nativeDead[wiseNum] == true then
+ SaveCampaignVar("M5WiseDead", "1")
+ else
+ SaveCampaignVar("M5WiseDead", "0")
+ end
+ if nativeDead[chiefNum] == true then
+ SaveCampaignVar("M5ChiefDead", "1")
+ else
+ SaveCampaignVar("M5ChiefDead", "0")
+ end
+ SaveCampaignVar("M5Choice", "" .. choice)
+ if progress and progress<5 then
+ SaveCampaignVar("Progress", "5")
+ end
+
+ for i = 1, 7 do
+ if natives[i] == deployedHog then
+ SaveCampaignVar("M5DeployedNum", "" .. i)
+ end
+ end
+
+ ParseCommand("teamgone " .. loc("Tribe"))
+ ParseCommand("teamgone " .. loc("Assault Team"))
+ ParseCommand("teamgone " .. loc("Reinforcements"))
+ ParseCommand("teamgone " .. loc("011101001"))
+ TurnTimeLeft = 0
+end
+
+-----------------------------Misc--------------------------------------
+
+function SpawnCrates()
+ SpawnAmmoCrate(0, 0, amDrill)
+ SpawnAmmoCrate(0, 0, amGrenade)
+ SpawnAmmoCrate(0, 0, amBazooka)
+ SpawnAmmoCrate(0, 0, amDynamite)
+ SpawnAmmoCrate(0, 0, amGrenade)
+ SpawnAmmoCrate(0, 0, amMine)
+ SpawnAmmoCrate(0, 0, amShotgun)
+ SpawnAmmoCrate(0, 0, amFlamethrower)
+ SpawnAmmoCrate(0, 0, amMolotov)
+ SpawnAmmoCrate(0, 0, amSMine)
+ SpawnAmmoCrate(0, 0, amMortar)
+ SpawnUtilityCrate(0, 0, amRope)
+ SpawnUtilityCrate(0, 0, amRope)
+ SpawnUtilityCrate(0, 0, amParachute)
+ SpawnUtilityCrate(0, 0, amParachute)
+ SetHealth(SpawnHealthCrate(0, 0), 25)
+ SetHealth(SpawnHealthCrate(0, 0), 25)
+ SetHealth(SpawnHealthCrate(0, 0), 25)
+ SetHealth(SpawnHealthCrate(0, 0), 25)
+ SetHealth(SpawnHealthCrate(0, 0), 25)
+ SetHealth(SpawnHealthCrate(0, 0), 25)
+end
+
+
+function RestoreWave(index)
+ for i = (index - 1) * 3 + 1, index * 3 do
+ if cannibalHidden[i] == true then
+ RestoreHog(cannibals[i])
+ AnimSetGearPosition(cannibals[i], unpack(cannibalPos[i]))
+ FollowGear(cannibals[i])
+ cannibalHidden[i] = false
+ end
+ end
+end
+
+function GetVariables()
+ progress = tonumber(GetCampaignVar("Progress"))
+ m2DenseDead = tonumber(GetCampaignVar("M2DenseDead"))
+ m2Choice = tonumber(GetCampaignVar("M2Choice"))
+ m4DenseDead = tonumber(GetCampaignVar("M4DenseDead"))
+ m4LeaksDead = tonumber(GetCampaignVar("M4LeaksDead"))
+ m4ChiefDead = tonumber(GetCampaignVar("M4ChiefDead"))
+ m4WaterDead = tonumber(GetCampaignVar("M4WaterDead"))
+ m4BuffaloDead = tonumber(GetCampaignVar("M4BuffaloDead"))
+end
+
+function HideCyborg()
+ if cyborgHidden == false then
+ HideHog(cyborg)
+ cyborgHidden = true
+ end
+end
+
+function RestoreCyborg()
+ if cyborgHidden == true then
+ RestoreHog(cyborg)
+ cyborgHidden = false
+ end
+end
+
+function SetupPlace()
+ startNativesNum = nativesNum
+ HideHog(cyborg)
+ cyborgHidden = true
+ for i = 1, 9 do
+ HideHog(cannibals[i])
+ cannibalHidden[i] = true
+ end
+ if m4LeaksDead == 1 then
+ HideHog(natives[leaksNum])
+ nativeHidden[leaksNum] = true
+ needRevival = true
+ end
+ if m4DenseDead == 1 then
+ if m2Choice ~= choiceAccepted then
+ DeleteGear(natives[denseNum])
+ startNativesNum = startNativesNum - 1
+ nativeDead[denseNum] = true
+ else
+ HideHog(natives[denseNum])
+ nativeHidden[denseNum] = true
+ needRevival = true
+ end
+ end
+ if m4WaterDead == 1 then
+ HideHog(natives[waterNum])
+ nativeHidden[waterNum] = true
+ needRevival = true
+ end
+ if m4ChiefDead == 1 then
+ DeleteGear(natives[chiefNum])
+ startNativesNum = startNativesNum - 1
+ nativeDead[chiefNum] = true
+ AnimSetGearPosition(natives[girlNum], unpack(nativePos[buffaloNum]))
+ nativePos[girlNum] = nativePos[buffaloNum]
+ end
+ if m4BuffaloDead == 1 then
+ startNativesNum = startNativesNum - 1
+ nativeDead[buffaloNum] = true
+ DeleteGear(natives[buffaloNum])
+ end
+ PlaceGirder(3568, 1461, 1)
+ PlaceGirder(440, 523, 5)
+ PlaceGirder(350, 441, 1)
+ PlaceGirder(405, 553, 5)
+ PlaceGirder(316, 468, 1)
+ PlaceGirder(1319, 168, 0)
+end
+
+function SetupAmmo()
+ AddAmmo(natives[girlNum], amSwitch, 0)
+end
+
+function AddHogs()
+ AddTeam(loc("Natives"), 29439, "Bone", "Island", "HillBilly", "cm_birdy")
+ for i = 1, 7 do
+ natives[i] = AddHog(nativeNames[i], 0, 100, nativeHats[i])
+ end
+ nativesNum = 7
+
+ AddTeam(loc("Tribe"), 29438, "Bone", "Island", "HillBilly", "cm_birdy")
+ for i = 8, 9 do
+ natives[i] = AddHog(nativeNames[i], 0, 100, nativeHats[i])
+ end
+
+
+ AddTeam(loc("Assault Team"), 14483456, "Skull", "Island", "Pirate", "cm_vampire")
+ for i = 1, 6 do
+ cannibals[i] = AddHog(cannibalNames[i], 1, 50, "vampirichog")
+ end
+
+ AddTeam(loc("Reinforcements"), 14483456, "Skull", "Island", "Pirate", "cm_vampire")
+ for i = 7, 9 do
+ cannibals[i] = AddHog(cannibalNames[i], 1, 50, "vampirichog")
+ end
+
+ AddTeam(loc("011101001"), 14483456, "ring", "UFO", "Robot", "cm_star")
+ cyborg = AddHog(loc("Unit 334a$7%;.*"), 0, 200, "cyborg1")
+
+ for i = 1, 9 do
+ AnimSetGearPosition(natives[i], unpack(nativePos[i]))
+ AnimTurn(natives[i], nativeDir[i])
+ end
+
+ AnimSetGearPosition(cyborg, 0, 0)
+
+ for i = 1, 9 do
+ AnimSetGearPosition(cannibals[i], cannibalPos[i][1], cannibalPos[i][2] + 40)
+ AnimTurn(cannibals[i], cannibalDir[i])
+ end
+end
+
+function CondNeedToTurn(hog1, hog2)
+ xl, xd = GetX(hog1), GetX(hog2)
+ if xl > xd then
+ AnimInsertStepNext({func = AnimTurn, args = {hog1, "Left"}})
+ AnimInsertStepNext({func = AnimTurn, args = {hog2, "Right"}})
+ elseif xl < xd then
+ AnimInsertStepNext({func = AnimTurn, args = {hog2, "Left"}})
+ AnimInsertStepNext({func = AnimTurn, args = {hog1, "Right"}})
+ end
+end
+
+-----------------------------Main Functions----------------------------
+
+function onGameInit()
+ Seed = 2
+ GameFlags = gfSolidLand
+ TurnTime = 60000
+ CaseFreq = 0
+ MinesNum = 0
+ MinesTime = 3000
+ Explosives = 0
+ Delay = 10
+ Map = "Cave"
+ Theme = "Nature"
+ SuddenDeathTurns = 3000
+
+ AddHogs()
+ AnimInit()
+end
+
+function onGameStart()
+ GetVariables()
+ SetupAmmo()
+ SetupPlace()
+ AnimationSetup()
+ AddAnim(startAnim)
+ AddFunction({func = AfterStartAnim, args = {}})
+end
+
+function onGameTick()
+ AnimUnWait()
+ if ShowAnimation() == false then
+ return
+ end
+ ExecuteAfterAnimations()
+ CheckEvents()
+end
+
+function onGearDelete(gear)
+ for i = 1, 7 do
+ if gear == natives[i] then
+ if nativeDead[i] ~= true then
+ freshDead = nativeNames[i]
+ end
+ nativeDead[i] = true
+ nativesNum = nativesNum - 1
+ end
+ end
+
+ for i = 1, 9 do
+ if gear == cannibals[i] then
+ cannibalDead[i] = true
+ end
+ end
+
+ if gear == spyHog and stage == spyKillStage then
+ freshDead = nil
+ choice = choiceEliminate
+ tmpVar = 1
+ end
+
+ if gear == deployedHog then
+ deployedDead = true
+ end
+end
+
+function onAmmoStoreInit()
+ SetAmmo(amDEagle, 9, 0, 0, 0)
+ SetAmmo(amSniperRifle, 4, 0, 0, 0)
+ SetAmmo(amFirePunch, 9, 0, 0, 0)
+ SetAmmo(amWhip, 9, 0, 0, 0)
+ SetAmmo(amBaseballBat, 9, 0, 0, 0)
+ SetAmmo(amHammer, 9, 0, 0, 0)
+ SetAmmo(amLandGun, 9, 0, 0, 0)
+ SetAmmo(amSnowball, 8, 0, 0, 0)
+ SetAmmo(amGirder, 4, 0, 0, 2)
+ SetAmmo(amParachute, 4, 0, 0, 2)
+ SetAmmo(amSwitch, 8, 0, 0, 2)
+ SetAmmo(amSkip, 8, 0, 0, 0)
+ SetAmmo(amRope, 5, 0, 0, 3)
+ SetAmmo(amBlowTorch, 3, 0, 0, 3)
+ SetAmmo(amPickHammer, 0, 0, 0, 3)
+ SetAmmo(amLowGravity, 0, 0, 0, 2)
+ SetAmmo(amDynamite, 0, 0, 0, 3)
+ SetAmmo(amBazooka, 4, 0, 0, 4)
+ SetAmmo(amGrenade, 4, 0, 0, 4)
+ SetAmmo(amMine, 2, 0, 0, 2)
+ SetAmmo(amSMine, 2, 0, 0, 2)
+ SetAmmo(amMolotov, 2, 0, 0, 3)
+ SetAmmo(amFlamethrower, 2, 0, 0, 3)
+ SetAmmo(amShotgun, 4, 0, 0, 4)
+ SetAmmo(amTeleport, 0, 0, 0, 2)
+ SetAmmo(amDrill, 0, 0, 0, 4)
+ SetAmmo(amMortar, 0, 0, 0, 4)
+end
+
+j = 0
+
+function onNewTurn()
+ tmpVar = 0
+ if AnimInProgress() then
+ TurnTimeLeft = -1
+ return
+ end
+
+ if GetHogTeamName(CurrentHedgehog) == loc("Tribe") then
+ TurnTimeLeft = 0
+ return
+ end
+ TurnsLeft = TurnsLeft - 1
+
+ if stage == platformStage then
+ AddCaption(TurnsLeft .. " turns until arrival!")
+ end
+
+ if stage == spyKillStage then
+ if CurrentHedgehog == spyHog or GetHogTeamName(CurrentHedgehog) ~= loc("Natives") then
+ TurnTimeLeft = 0
+ else
+ SetGearMessage(CurrentHedgehog, 0)
+ --AnimSwitchHog(natives[leaksNum])
+ TurnTimeLeft = -1
+ end
+ else
+ if freshDead ~= nil and GetHogTeamName(CurrentHedgehog) == loc("Natives") then
+ SetupHogDeadAnim(freshDead)
+ AddAnim(hogDeadAnim)
+ AddFunction({func = AfterHogDeadAnim, args = {}})
+ end
+ end
+ if needToAct > 0 then
+ if needToAct == 1 then
+ RestoreWave(2)
+ SetupWave2Anim()
+ AddAnim(wave2Anim)
+ AddFunction({func = AfterWave2Anim, args = {}})
+ elseif needToAct == 2 then
+ SetupWave2DeadAnim()
+ AddAnim(wave2DeadAnim)
+ AddFunction({func = AfterWave2DeadAnim, args = {}})
+ elseif needToAct == 3 then
+ AnimSwitchHog(deployedHog)
+ AddFunction({func = AddWave3DeadAnim, args = {}})
+ end
+ needToAct = 0
+ end
+end
+
+function onPrecise()
+ if GameTime > 2500 and AnimInProgress() then
+ SetAnimSkip(true)
+ return
+ end
+ if stage == spyKillStage then
+ highJumped = true
+ end
+end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Missions/Campaign/A_Classic_Fairytale/campaign.ini Mon Jul 01 23:23:22 2013 +0300
@@ -0,0 +1,42 @@
+MissionNum=10
+ResetRetry=1
+
+[Mission 1]
+Name=First Blood
+Script=first_blood.lua
+
+[Mission 2]
+Name=The Shadow Falls
+Script=shadow.lua
+
+[Mission 3]
+Name=The Journey Back
+Script=journey.lua
+
+[Mission 4]
+Name=United We Stand
+Script=united.lua
+
+[Mission 5]
+Name=Backstab
+Script=backstab.lua
+
+[Mission 6]
+Name=Dragon's Lair
+Script=dragon.lua
+
+[Mission 7]
+Name=Family Reunion
+Script=family.lua
+
+[Mission 8]
+Name=Long Live The Queen
+Script=queen.lua
+
+[Mission 9]
+Name=The Enemy Of My Enemy
+Script=enemy.lua
+
+[Mission 10]
+Name=Epilogue
+Script=epil.lua
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Missions/Campaign/A_Classic_Fairytale/dragon.lua Mon Jul 01 23:23:22 2013 +0300
@@ -0,0 +1,652 @@
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Animate.lua")
+
+-----------------------------Map--------------------------------------
+local map =
+{
+ "\0\91\4\253\131\0\88\0\46\0\0\91\0\49\131\15\196\0\53\0\15\196\0\53\131\15\196\4\250\0\255\242\7\179\131\1\128\7\214\0",
+ "\1\113\7\207\131\3\182\7\157\0\3\175\7\143\131\6\58\7\200\0\6\76\7\193\131\6\188\7\129\0\6\188\7\129\131\6\248\6\216\0",
+ "\6\248\6\216\131\7\52\8\14\0\10\206\8\0\131\11\203\6\65\0\11\203\6\65\131\12\18\7\66\0\12\18\7\69\131\16\0\7\69\0",
+ "\0\109\1\1\131\2\111\0\49\0\2\111\0\49\131\3\133\1\18\0\3\140\1\18\131\4\162\0\165\0\4\162\0\165\131\5\135\1\29\0",
+ "\5\145\1\22\131\8\84\0\232\0\8\84\0\232\131\9\26\0\70\0\9\26\0\70\131\10\5\1\4\0\10\48\0\243\131\10\2\1\8\0",
+ "\10\58\0\243\131\10\118\1\15\0\10\118\1\15\131\10\234\1\173\0\11\10\1\177\131\12\11\1\22\0\12\39\1\40\131\12\243\2\9\0",
+ "\12\243\2\9\131\13\106\0\165\0\13\131\0\176\131\15\186\1\78\0\1\244\0\81\136\0\120\0\84\0\1\99\0\123\137\0\130\0\215\0",
+ "\0\158\0\130\143\0\158\0\130\0\2\216\0\88\138\4\165\0\102\0\4\91\0\127\142\3\129\0\197\0\3\69\0\134\142\3\69\0\134\0",
+ "\4\215\0\120\143\8\88\0\134\0\8\187\0\84\139\8\187\0\84\0\8\239\0\70\135\8\239\0\70\0\8\60\0\187\138\5\99\0\222\0",
+ "\5\61\0\197\138\5\61\0\197\0\9\99\0\81\137\10\23\0\218\0\9\187\0\77\137\11\31\1\117\0\10\30\0\88\137\15\161\0\109\0",
+ "\15\126\0\225\144\13\177\0\116\0\15\150\0\144\139\15\157\1\26\0\10\202\0\169\152\12\246\0\169\0\10\72\0\144\145\11\122\1\36\0",
+ "\11\17\1\121\141\11\17\1\121\0\12\229\1\194\138\12\229\1\194\0\12\208\1\85\150\12\208\1\85\0\12\148\1\15\147\12\148\1\15\0",
+ "\13\145\0\208\147\13\145\0\208\0\6\238\7\45\135\7\10\7\238\0\6\220\7\150\135\6\206\7\242\0\6\174\7\175\135\6\135\8\7\0",
+ "\6\118\7\214\135\6\62\7\238\0\6\30\7\245\140\3\217\7\210\0\3\161\7\221\138\255\252\7\231\0\15\242\7\165\148\11\115\7\175\0",
+ "\11\196\6\164\138\11\10\8\4\0\11\210\7\31\141\11\210\7\31\0\14\216\2\72\166\14\216\2\72\0\14\213\4\4\166\14\213\4\4\0",
+ "\13\216\1\159\148\13\216\1\159\0\13\159\2\143\148\13\159\2\143\0\13\230\3\69\145\13\230\3\69\0\13\163\4\11\145\13\166\4\11\0",
+ "\13\237\4\208\145\13\237\4\208\0\14\195\5\61\145\14\195\5\61\0\13\78\1\254\136\13\78\1\254\0\12\239\2\93\136\12\239\2\93\0",
+ "\12\250\2\227\136\12\250\2\227\0\13\71\3\59\136\13\71\3\59\0\13\1\3\168\136\13\1\3\168\0\12\243\4\32\136\12\246\4\32\0",
+ "\13\40\4\130\136\13\43\4\134\0\13\92\4\243\136\13\92\4\243\0\13\142\5\135\136\13\142\5\135\0\14\33\5\106\136\14\33\5\106\0",
+ "\14\111\5\208\136\14\121\5\216\0\15\13\5\237\136\15\13\5\237\0\15\73\5\128\136\15\73\5\128\0\15\84\4\243\136\15\84\4\243\0",
+ "\14\199\6\33\133\14\199\6\33\0\14\97\6\44\133\14\83\6\44\0\14\9\5\240\133\14\9\5\240\0\13\226\5\163\133\13\226\5\163\0",
+ "\13\170\5\233\133\13\170\5\233\0\13\71\5\205\133\13\71\5\205\0\13\61\5\117\133\13\61\5\117\0\13\22\5\40\133\13\22\5\40\0",
+ "\12\253\4\211\133\12\253\4\211\0\12\197\4\169\133\12\197\4\169\0\12\204\4\106\133\12\204\4\106\0\12\162\4\46\133\12\162\4\42\0",
+ "\12\194\3\200\133\12\194\3\196\0\12\201\3\84\133\12\201\3\84\0\12\253\3\62\133\12\253\3\62\0\12\169\2\241\133\12\169\2\241\0",
+ "\12\187\2\167\133\12\187\2\167\0\12\158\2\93\133\12\158\2\93\0\12\162\2\9\133\12\162\2\9\0\12\123\1\205\132\12\123\1\205\0",
+ "\12\84\1\251\132\12\84\1\251\0\12\91\2\55\132\12\95\2\55\0\12\63\2\139\132\12\63\2\139\0\12\120\2\164\132\12\120\2\164\0",
+ "\12\81\2\206\132\12\81\2\206\0\12\106\3\17\132\12\109\3\20\0\12\137\3\73\132\12\137\3\73\0\12\84\3\122\132\12\84\3\122\0",
+ "\12\137\3\150\132\12\137\3\150\0\12\95\3\217\132\12\95\3\217\0\12\134\3\231\132\12\134\3\231\0\12\106\4\63\132\12\106\4\63\0",
+ "\12\137\4\120\132\12\141\4\120\0\12\88\4\179\132\12\88\4\183\0\12\134\4\190\132\12\134\4\190\0\12\158\4\232\132\12\165\4\232\0",
+ "\12\215\5\15\132\12\215\5\15\0\12\91\4\243\130\12\91\4\243\0\12\144\5\26\130\12\144\5\26\0\12\176\5\54\130\12\176\5\54\0",
+ "\12\225\5\82\130\12\225\5\82\0\13\4\5\117\130\13\1\5\117\0\12\239\5\166\130\12\239\5\166\0\13\8\5\184\130\13\11\5\184\0",
+ "\13\8\5\226\130\13\8\5\226\0\13\54\6\12\130\13\57\6\12\0\13\106\6\2\130\13\106\5\254\0\13\138\6\12\130\13\138\6\12\0",
+ "\13\184\6\30\130\13\187\6\30\0\13\223\5\254\130\13\223\5\254\0\13\149\6\69\130\13\145\6\69\0\13\128\6\33\130\13\128\6\33\0",
+ "\13\85\6\40\130\13\85\6\40\0\12\232\6\2\130\12\232\6\2\0\12\204\5\205\130\12\204\5\201\0\12\183\5\159\130\12\183\5\156\0",
+ "\12\211\5\128\130\12\211\5\128\0\12\165\5\103\130\12\165\5\103\0\12\123\5\64\130\12\120\5\64\0\12\81\5\71\130\12\81\5\71\0",
+ "\12\84\5\18\130\12\84\5\18\0\12\39\4\243\130\12\39\4\243\0\12\35\4\194\130\12\35\4\194\0\12\63\4\127\130\12\63\4\127\0",
+ "\12\91\4\106\130\12\91\4\106\0\12\53\4\60\130\12\53\4\60\0\12\74\4\25\130\12\84\4\21\0\12\120\4\4\130\12\120\4\4\0",
+ "\12\42\3\231\130\12\42\3\231\0\12\39\3\189\130\12\42\3\186\0\12\60\3\175\130\12\60\3\175\0\12\39\3\133\130\12\39\3\133\0",
+ "\12\70\3\73\130\12\70\3\73\0\12\25\3\77\130\12\25\3\77\0\12\42\3\13\130\12\46\3\13\0\12\81\3\31\130\12\81\3\31\0",
+ "\12\32\2\213\130\12\32\2\213\0\12\14\2\178\130\12\14\2\178\0\12\42\2\181\130\12\46\2\181\0\12\14\2\128\130\12\14\2\128\0",
+ "\12\39\2\100\130\12\42\2\100\0\12\74\2\104\130\12\77\2\104\0\12\106\2\135\130\12\109\2\135\0\12\39\2\72\130\12\39\2\69\0",
+ "\12\35\2\37\130\12\35\2\37\0\12\32\2\2\130\12\32\2\2\0\12\28\1\226\130\12\28\1\223\0\12\63\1\208\130\12\63\1\208\0",
+ "\12\84\1\173\130\12\84\1\170\0\12\63\1\159\130\12\60\1\159\0\12\39\1\113\130\12\39\1\113\0\12\14\1\96\130\12\11\1\96\0",
+ "\11\228\1\131\130\11\228\1\135\0\12\7\1\149\130\12\7\1\149\0\12\21\1\177\130\12\25\1\177\0\11\242\1\201\130\11\242\1\201\0",
+ "\13\226\6\58\130\13\226\6\58\0\14\16\6\40\130\14\16\6\40\0\13\208\6\86\130\13\208\6\86\0\13\247\6\111\130\13\247\6\114\0",
+ "\13\184\6\121\130\13\184\6\121\0\13\198\6\146\130\13\201\6\146\0\13\244\6\139\130\13\244\6\139\0\13\223\6\185\130\13\223\6\185\0",
+ "\13\173\6\199\130\13\173\6\199\0\13\159\6\171\130\13\159\6\171\0\13\138\6\220\130\13\138\6\220\0\13\184\6\238\130\13\184\6\238\0",
+ "\13\208\6\223\130\13\208\6\223\0\13\216\7\10\130\13\216\7\10\0\13\184\7\10\130\13\180\7\10\0\13\142\7\38\130\13\142\7\41\0",
+ "\13\128\7\6\130\13\128\7\6\0\13\85\7\34\130\13\89\7\34\0\13\89\7\3\130\13\89\7\3\0\13\117\6\220\130\13\121\6\220\0",
+ "\13\75\6\195\130\13\75\6\195\0\13\110\6\164\130\13\110\6\164\0\13\156\6\125\130\13\156\6\125\0\13\106\6\135\130\13\106\6\135\0",
+ "\13\103\6\100\130\13\103\6\100\0\13\64\6\143\130\13\64\6\143\0\13\47\6\104\130\13\47\6\104\0\13\71\6\79\130\13\71\6\79\0",
+ "\13\40\6\65\130\13\36\6\65\0\13\8\6\44\130\13\1\6\44\0\13\8\6\76\130\13\8\6\76\0\13\1\6\132\130\13\1\6\132\0",
+ "\13\33\6\135\130\13\33\6\135\0\13\26\6\178\130\13\22\6\178\0\13\47\6\202\130\13\50\6\202\0\13\54\6\245\130\13\54\6\245\0",
+ "\13\22\7\3\130\13\22\7\3\0\13\43\7\27\130\13\43\7\27\0\12\253\6\248\130\12\250\6\248\0\12\253\6\220\130\12\253\6\220\0",
+ "\12\215\6\174\130\12\225\6\174\0\12\253\6\174\130\12\253\6\174\0\12\215\6\121\130\12\215\6\121\0\12\229\6\76\130\12\229\6\76\0",
+ "\12\201\6\51\130\12\201\6\51\0\12\190\6\19\130\12\190\6\19\0\12\151\5\223\130\12\151\5\223\0\12\148\5\194\130\12\151\5\194\0",
+ "\12\155\5\159\130\12\155\5\156\0\12\144\5\121\130\12\144\5\121\0\12\95\5\110\130\12\95\5\110\0\12\102\5\156\130\12\102\5\159\0",
+ "\12\99\5\216\130\12\106\5\219\0\12\148\6\40\130\12\148\6\40\0\12\127\6\19\130\12\127\6\19\0\12\176\6\104\130\12\176\6\104\0",
+ "\12\141\6\72\130\12\141\6\72\0\12\162\6\139\130\12\162\6\143\0\12\172\6\181\130\12\172\6\181\0\12\204\6\216\130\12\208\6\216\0",
+ "\12\201\7\3\130\12\201\7\3\0\12\236\7\24\130\12\236\7\24\0\12\120\6\146\130\12\120\6\146\0\12\123\6\104\130\12\123\6\104\0",
+ "\12\123\6\185\130\12\123\6\185\0\12\162\6\227\130\12\162\6\227\0\12\134\6\241\130\12\134\6\241\0\12\155\7\10\130\12\155\7\10\0",
+ "\12\190\7\41\130\12\190\7\41\0\11\228\1\96\129\11\228\1\96\0\11\200\1\121\129\11\200\1\121\0\11\193\1\156\129\11\196\1\156\0",
+ "\11\221\1\170\129\11\221\1\170\0\11\217\1\208\129\11\217\1\208\0\11\245\1\230\129\11\245\1\230\0\11\245\2\16\129\11\245\2\16\0",
+ "\12\14\2\62\129\12\18\2\62\0\11\242\2\93\129\11\242\2\93\0\11\235\2\178\129\11\235\2\178\0\11\231\2\238\129\11\235\2\238\0",
+ "\12\4\2\252\129\12\4\2\252\0\11\252\3\34\129\11\252\3\34\0\11\235\3\87\129\11\238\3\87\0\12\11\3\119\129\12\11\3\119\0",
+ "\12\4\3\168\129\12\4\3\168\0\11\245\3\200\129\11\245\3\200\0\11\252\3\238\129\11\252\3\242\0\12\11\4\7\129\12\11\4\7\0",
+ "\11\245\4\60\129\11\238\4\60\0\11\224\4\74\129\11\221\4\74\0\11\210\4\137\129\11\210\4\137\0\11\228\4\151\129\11\231\4\151\0",
+ "\11\242\4\130\129\11\242\4\130\0\12\4\4\113\129\12\7\4\113\0\12\28\4\102\129\12\28\4\102\0\12\11\4\141\129\12\11\4\141\0",
+ "\11\249\4\162\129\11\249\4\162\0\11\221\4\116\129\11\221\4\116\0\11\214\4\106\129\11\217\4\102\0\12\4\4\211\129\12\4\4\211\0",
+ "\11\249\5\8\129\11\252\5\8\0\12\39\5\11\129\12\42\5\11\0\12\56\5\50\129\12\60\5\47\0\12\46\5\96\129\12\49\5\96\0",
+ "\12\70\5\113\129\12\70\5\113\0\12\56\5\166\129\12\63\5\166\0\12\70\5\145\129\12\74\5\145\0\12\70\5\194\129\12\77\5\194\0",
+ "\12\70\5\237\129\12\74\5\237\0\12\106\5\240\129\12\109\5\240\0\12\99\6\33\129\12\99\6\33\0\12\88\6\72\129\12\88\6\72\0",
+ "\12\91\6\107\129\12\95\6\107\0\12\77\6\146\129\12\81\6\146\0\12\88\6\181\129\12\91\6\181\0\12\91\6\220\129\12\99\6\220\0",
+ "\12\113\7\10\129\12\116\7\10\0\8\116\4\18\179\8\116\4\18\0\9\205\3\73\156\9\205\3\73\0\10\83\2\146\144\10\83\2\146\0",
+ "\10\153\2\44\136\10\153\2\44\0\10\181\1\240\132\10\181\1\240\0\10\199\1\205\131\10\199\1\205\0\10\209\1\184\129\10\209\1\184\0",
+ "\8\42\2\167\150\8\42\2\167\0\8\53\1\240\141\8\53\1\237\0\8\67\1\135\134\8\67\1\135\0\11\224\5\8\129\11\224\5\8\0",
+ "\11\200\5\8\129\11\200\5\8\0\11\182\5\8\129\11\182\5\8\0\11\154\5\4\129\11\154\5\4\0\11\129\5\8\129\11\129\5\8\0",
+ "\11\119\3\84\129\11\119\3\84\0\11\140\3\87\129\11\140\3\87\0\11\165\3\87\129\11\165\3\87\0\11\182\3\87\129\11\182\3\87\0",
+ "\11\203\3\87\129\11\203\3\87\0\9\33\6\223\132\9\33\8\11\0\9\33\6\188\129\9\33\6\188\0\0\123\1\26\136\0\211\2\223\0",
+ "\0\211\2\223\136\0\120\3\84\0\0\130\3\101\136\0\211\4\53\0\0\204\4\53\136\0\120\4\151\0\0\130\3\193\136\0\127\4\63\0",
+ "\0\130\3\31\136\0\130\1\201\0\0\91\4\253\130\0\91\6\76\0\7\94\3\136\138\7\94\3\136\0\7\24\3\77\135\7\24\3\77\0",
+ "\6\238\3\24\132\6\241\3\24\0\6\223\2\238\131\6\223\2\238\0\6\220\2\209\129\6\220\2\209\0\7\87\4\14\133\7\87\4\14\0",
+ "\7\38\4\0\131\7\38\4\0\0\7\6\3\242\130\7\6\3\242\0\6\241\3\228\129\6\241\3\228\0\6\227\3\217\128\6\227\3\217\0",
+ "\0\109\4\197\135\0\162\5\99\0\0\144\5\121\135\0\123\6\9\0\0\127\5\92\135\0\127\5\92\0\0\127\5\54\135\0\127\5\54\0",
+ "\0\134\6\23\132\0\236\6\97\0\0\236\6\97\132\1\106\6\135\0\1\117\6\135\132\1\177\6\143\0\2\234\7\80\130\3\69\7\80\0",
+ "\3\69\7\80\130\3\84\7\101\0\3\84\7\101\130\3\87\7\129\0\3\87\7\129\130\3\84\7\150\0\0\183\5\103\130\1\92\5\159\0",
+ "\1\11\5\138\130\0\253\5\180\0\0\253\5\180\130\0\158\5\166\0\0\239\4\60\131\1\166\4\95\0\2\104\3\133\131\3\84\3\129\0",
+ "\4\162\2\181\131\4\162\3\147\0\3\115\2\26\131\4\74\2\30\0\2\23\1\54\131\2\230\1\54\0\0\204\2\5\131\1\194\2\5\0",
+ "\4\74\2\33\131\5\226\1\223\0\0\225\5\121\197\1\135\5\163\0\0\204\5\173\197\1\1\5\173\0\0\179\5\152\131\1\57\5\163\0",
+ "\1\57\5\159\131\1\106\5\219\0\0\165\5\226\130\0\253\5\230\0\0\253\5\230\130\1\8\5\159\0\1\254\6\86\131\1\254\6\86\0",
+ "\1\254\6\33\131\1\254\6\33\0\1\254\5\230\131\1\254\5\230\0\1\254\5\170\131\1\254\5\170\0\1\254\5\113\131\1\254\5\113\0",
+ "\1\251\6\5\129\1\251\6\5\0\1\254\5\201\129\1\254\5\201\0\1\254\5\138\129\1\254\5\138\0\1\254\6\58\129\1\254\6\58\0",
+ "\1\254\5\78\129\1\254\5\78\0\2\2\5\40\131\2\2\5\40\0\2\2\4\246\131\2\2\4\246\0\1\237\4\204\131\1\237\4\204\0",
+ "\2\40\4\190\131\2\40\4\190\0\6\160\7\52\223\7\27\7\126\0\1\219\4\172\204\1\219\4\172\0\2\37\4\183\197\2\37\4\183\0",
+ "\3\98\3\122\131\3\126\3\84\0\3\126\3\84\131\3\126\3\52\0\3\126\3\41\131\3\80\3\24\0\3\80\3\24\131\3\112\2\248\0",
+ "\3\112\2\248\131\3\98\2\188\0",
+}
+
+
+-----------------------------Constants---------------------------------
+choiceAccepted = 1
+choiceRefused = 2
+choiceAttacked = 3
+
+choiceEliminate = 1
+choiceSpare = 2
+
+leaksNum = 1
+denseNum = 2
+waterNum = 3
+buffaloNum = 4
+chiefNum = 5
+girlNum = 6
+wiseNum = 7
+
+nativeNames = {loc("Leaks A Lot"), loc("Dense Cloud"), loc("Fiery Water"),
+ loc("Raging Buffalo"), loc("Righteous Beard"), loc("Fell From Grace"),
+ loc("Wise Oak")}
+
+nativeUnNames = {loc("Zork"), loc("Steve"), loc("Jack"),
+ loc("Lee"), loc("Elmo"), loc("Rachel"),
+ loc("Muriel")}
+
+nativeHats = {"Rambo", "RobinHood", "pirate_jack", "zoo_Bunny", "IndianChief",
+ "tiara", "AkuAku"}
+
+nativePos = {257, 1950}
+
+cyborgNames = {loc("Syntax Errol"), loc("Segmentation Paul"), loc("Unexpected Igor"), loc("Jeremiah")}
+cyborgPos = {745, 1847}
+cyborgsPos = {{2937, 831}, {2945, 1264}, {2335, 1701}, {448, 484}}
+cyborgsDir = {"Left", "Left", "Left", "Right"}
+
+cratePos = {
+ {788, 1919, amGirder, 2}, {412, 1615, amGirder, 1},
+ {209, 1474, amSniperRifle, 1}, {1178, 637, amDEagle, 1},
+ {633, 268, amDEagle, 1}, {3016, 1545, amDEagle, 1},
+ {249, 1377, amRope, 3}, {330, 1018, amGirder, 1},
+ {888, 647, amRope, 3}, {2116, 337, amRope, 3},
+ {1779, 948, amRope, 3}, {3090, 1066, amRope, 3},
+ {947, 480, amBazooka, 3}, {1097, 480, amMortar, 3},
+ {1139, 451, amSnowball, 3}, {1207, 468, amShotgun, 3},
+ {1024, 393, amSniperRifle, 2}, {998, 391, amDynamite, 2},
+ {1024, 343, amRope, 2}, {998, 341, amRope, 2}
+ }
+reactions = {loc("Yeah, take that!"), loc("Bullseye"), loc("Die, die, die!")}
+
+secondPos = {{1010, 510}, {1067, 510}}
+-----------------------------Variables---------------------------------
+natives = {}
+native = nil
+
+cyborgs = {}
+cyborg = {}
+cyborgsLeft = 0
+
+gearDead = {}
+hedgeHidden = {}
+
+startAnim = {}
+killAnim = {}
+killedAnim = {}
+
+freshDead = nil
+crates = {}
+cratesNum = 0
+jetCrate = nil
+-----------------------------Animations--------------------------------
+function EmitDenseClouds(dir)
+ local dif
+ if dir == "Left" then
+ dif = 10
+ else
+ dif = -10
+ end
+ AnimInsertStepNext({func = AnimVisualGear, args = {native, GetX(native) + dif, GetY(native) + dif, vgtSteam, 0, true}, swh = false})
+ AnimInsertStepNext({func = AnimVisualGear, args = {native, GetX(native) + dif, GetY(native) + dif, vgtSteam, 0, true}, swh = false})
+ AnimInsertStepNext({func = AnimVisualGear, args = {native, GetX(native) + dif, GetY(native) + dif, vgtSteam, 0, true}, swh = false})
+ AnimInsertStepNext({func = AnimWait, args = {native, 800}})
+ AnimInsertStepNext({func = AnimVisualGear, args = {native, GetX(native) + dif, GetY(native) + dif, vgtSteam, 0, true}, swh = false})
+ AnimInsertStepNext({func = AnimVisualGear, args = {native, GetX(native) + dif, GetY(native) + dif, vgtSteam, 0, true}, swh = false})
+ AnimInsertStepNext({func = AnimWait, args = {native, 800}})
+ AnimInsertStepNext({func = AnimVisualGear, args = {native, GetX(native) + dif, GetY(native) + dif, vgtSteam, 0, true}, swh = false})
+end
+
+function AnimationSetup()
+ startAnim = {}
+ local m = m5DeployedNum
+ table.insert(startAnim, {func = AnimWait, args = {native, 3000}})
+ table.insert(startAnim, {func = AnimCaption, args = {native, loc("With the rest of the tribe gone, it was up to ") .. nativeNames[m5DeployedNum] .. loc(" to save the village."), 5000}})
+ table.insert(startAnim, {func = AnimCaption, args = {native, loc("But it proved to be no easy task!"), 2000}})
+ for i = 1, 4 do
+ table.insert(startAnim, {func = FollowGear, swh = false, args = {cyborgs[i]}})
+ table.insert(startAnim, {func = AnimWait, args = {native, 1000}})
+ end
+ table.insert(startAnim, {func = FollowGear, swh = false, args = {native}})
+ if m == leaksNum then
+ table.insert(startAnim, {func = AnimMove, args = {native, "Right", nativePos[1] + 50, 0}})
+ table.insert(startAnim, {func = AnimSay, args = {native, loc("What a strange cave!"), SAY_THINK, 0}})
+ table.insert(startAnim, {func = AnimMove, args = {native, "Right", nativePos[1] + 200, 0}})
+ table.insert(startAnim, {func = AnimSay, args = {native, loc("Now how do I get on the other side?!"), SAY_THINK, 5500}})
+ elseif m == denseNum then
+ table.insert(startAnim, {func = AnimMove, args = {native, "Right", nativePos[1] + 50, 0}})
+ table.insert(startAnim, {func = AnimSay, args = {native, loc("Dude, what's this place?!"), SAY_THINK, 0}})
+ table.insert(startAnim, {func = AnimCustomFunction, args = {native, EmitDenseClouds, {"Right"}}})
+ table.insert(startAnim, {func = AnimMove, args = {native, "Right", nativePos[1] + 200, 0}})
+ table.insert(startAnim, {func = AnimSay, args = {native, loc("And where's all the weed?"), SAY_THINK, 4000}})
+ elseif m == waterNum then
+ table.insert(startAnim, {func = AnimMove, args = {native, "Right", nativePos[1] + 50, 0}})
+ table.insert(startAnim, {func = AnimSay, args = {native, loc("Is this place in my head?"), SAY_THINK, 0}})
+ table.insert(startAnim, {func = AnimMove, args = {native, "Right", nativePos[1] + 200, 0}})
+ table.insert(startAnim, {func = AnimSay, args = {native, loc("I shouldn't have drunk that last pint."), SAY_THINK, 6000}})
+ elseif m == buffaloNum then
+ table.insert(startAnim, {func = AnimMove, args = {native, "Right", nativePos[1] + 50, 0}})
+ table.insert(startAnim, {func = AnimSay, args = {native, loc("Where did that alien run?"), SAY_THINK, 0}})
+ table.insert(startAnim, {func = AnimMove, args = {native, "Right", nativePos[1] + 200, 0}})
+ table.insert(startAnim, {func = AnimSay, args = {native, loc("When I find it..."), SAY_THINK, 3000}})
+ elseif m == girlNum then
+ table.insert(startAnim, {func = AnimMove, args = {native, "Right", nativePos[1] + 50, 0}})
+ table.insert(startAnim, {func = AnimSay, args = {native, loc("This is typical!"), SAY_THINK, 0}})
+ table.insert(startAnim, {func = AnimMove, args = {native, "Right", nativePos[1] + 200, 0}})
+ table.insert(startAnim, {func = AnimSay, args = {native, loc("It's always up to women to clear up the mess men created!"), SAY_THINK, 8500}})
+ elseif m == chiefNum then
+ table.insert(startAnim, {func = AnimMove, args = {native, "Right", nativePos[1] + 50, 0}})
+ table.insert(startAnim, {func = AnimSay, args = {native, loc("What is this place?"), SAY_THINK, 0}})
+ table.insert(startAnim, {func = AnimMove, args = {native, "Right", nativePos[1] + 200, 0}})
+ table.insert(startAnim, {func = AnimSay, args = {native, loc("It doesn't matter. I won't let that alien hurt my daughter!"), SAY_THINK, 8500}})
+ elseif m == wiseNum then
+ table.insert(startAnim, {func = AnimMove, args = {native, "Right", nativePos[1] + 50, 0}})
+ table.insert(startAnim, {func = AnimSay, args = {native, loc("Every single time!"), SAY_THINK, 0}})
+ table.insert(startAnim, {func = AnimMove, args = {native, "Right", nativePos[1] + 200, 0}})
+ table.insert(startAnim, {func = AnimSay, args = {native, loc("How come in a village full of warriors, it's up to me to save it?"), SAY_THINK, 8500}})
+ end
+
+ table.insert(startAnim, {func = AnimCustomFunction, args = {native, RestoreHedge, {cyborg, unpack(cyborgPos)}}})
+ table.insert(startAnim, {func = AnimOutOfNowhere, args = {cyborg, unpack(cyborgPos)}})
+ table.insert(startAnim, {func = AnimTurn, args = {cyborg, "Left"}})
+ table.insert(startAnim, {func = AnimSay, args = {cyborg, loc("Greetings, ") .. nativeUnNames[m] .. "!", SAY_SAY, 2500}})
+ table.insert(startAnim, {func = AnimSay, args = {cyborg, loc("As you can see, there is no way to get on the other side!"), SAY_SAY, 7000}})
+ table.insert(startAnim, {func = AnimSay, args = {cyborg, loc("I wish to help you, ") .. nativeUnNames[m] .. "!", SAY_SAY, 4000}})
+ table.insert(startAnim, {func = AnimSay, args = {cyborg, loc("Beware, though! If you are slow, you die!"), SAY_SAY, 7000}})
+ table.insert(startAnim, {func = AnimDisappear, args = {cyborg, unpack(cyborgPos)}})
+ table.insert(startAnim, {func = AnimSwitchHog, args = {native}})
+ table.insert(startAnim, {func = AnimCustomFunction, args = {native, HideHedge, {cyborg}}})
+ table.insert(startAnim, {func = AnimSay, args = {native, loc("Talk about mixed signals..."), SAY_SAY, 4000}})
+ AddSkipFunction(startAnim, SkipStartAnim, {})
+end
+
+function SetupKillAnim()
+ table.insert(killAnim, {func = AnimSay, args = {native, loc("Well, that was a waste of time."), SAY_THINK, 5000}})
+ table.insert(killAnim, {func = AnimCustomFunction, args = {native, RestoreHedge, {cyborg, unpack(cyborgPos)}}})
+ table.insert(killAnim, {func = AnimOutOfNowhere, args = {cyborg, unpack(cyborgPos)}})
+ table.insert(killAnim, {func = AnimCustomFunction, args = {cyborg, CondNeedToTurn, {cyborg, native}}})
+ table.insert(killAnim, {func = AnimSay, args = {cyborg, loc("You bear impressive skills, ") .. nativeUnNames[m5DeployedNum] .. "!", SAY_SHOUT, 4000}})
+ table.insert(killAnim, {func = AnimSay, args = {cyborg, loc("However, my mates don't agree with me on letting you go..."), SAY_SHOUT, 7000}})
+ table.insert(killAnim, {func = AnimSay, args = {cyborg, loc("I guess you'll have to kill them."), SAY_SHOUT, 4000}})
+ table.insert(killAnim, {func = AnimDisappear, args = {cyborg, unpack(cyborgPos)}})
+ table.insert(killAnim, {func = AnimSwitchHog, args = {native}})
+ table.insert(killAnim, {func = AnimWait, args = {native, 1}})
+ table.insert(killAnim, {func = AnimCustomFunction, args = {native, HideHedge, {cyborg}}})
+ AddSkipFunction(killAnim, SkipKillAnim, {})
+end
+
+function SetupKilledAnim()
+ table.insert(killedAnim, {func = AnimWait, args = {cyborg, 500}})
+ table.insert(killedAnim, {func = AnimOutOfNowhere, args = {cyborg, unpack(secondPos[2])}})
+ table.insert(killedAnim, {func = AnimOutOfNowhere, args = {native, unpack(secondPos[1])}})
+ table.insert(killedAnim, {func = AnimCustomFunction, args = {cyborg, CondNeedToTurn, {cyborg, native}}})
+ table.insert(killedAnim, {func = AnimSay, args = {cyborg, loc("Nice work, ") .. nativeUnNames[m5DeployedNum] .. "!", SAY_SHOUT, 4000}})
+ table.insert(killedAnim, {func = AnimSay, args = {cyborg, loc("As a reward for your performance, here's some new technology!"), SAY_SHOUT, 8000}})
+ table.insert(killedAnim, {func = AnimSay, args = {cyborg, loc("Use it wisely!"), SAY_SHOUT, 3000}})
+ table.insert(killedAnim, {func = AnimDisappear, args = {cyborg, unpack(secondPos[2])}})
+ table.insert(killedAnim, {func = AnimSwitchHog, args = {native}})
+ AddSkipFunction(killedAnim, SkipKilledAnim, {})
+end
+--------------------------Anim skip functions--------------------------
+function SkipStartAnim()
+ AnimSwitchHog(native)
+ AnimWait(native, 1)
+ AddFunction({func = HideHedge, args = {cyborg}})
+end
+
+function AfterStartAnim()
+ SetGearMessage(native, 0)
+ cratesNum = 0
+ for i = 1, 6 do
+ crates[i] = SpawnAmmoCrate(unpack(cratePos[i]))
+ cratesNum = cratesNum + 1
+ end
+ FollowGear(native)
+ AddNewEvent(CheckGearsDead, {{crates[1], crates[2]}}, PutCrates, {2}, 0)
+ TurnTimeLeft = TurnTime
+ ShowMission(loc("Dragon's Lair"), loc("Obstacle course"), loc("In order to get to the other side, you need to collect the crates first.|") ..
+ loc("As the ammo is sparse, you might want to reuse ropes while mid-air.|") ..
+ loc("If you wish to restart the course, hold [Precise] while your turn ends (e.g with Skip)!|") ..
+ loc("The enemy can't move but it might be a good idea to stay out of sight!|") ..
+ loc("You have ") .. SuddenDeathTurns .. loc(" turns until Sudden Death! Better hurry!"), 1, 0)
+end
+
+function SkipKillAnim()
+ AnimSwitchHog(native)
+ AnimWait(native, 1)
+ AddFunction({func = HideHedge, args = {cyborg}})
+end
+
+function AfterKillAnim()
+ PutWeaponCrates()
+ TurnTimeLeft = TurnTime
+ AddEvent(CheckCyborgsDead, {}, DoCyborgsDead, {}, 0)
+ ShowMission(loc("Dragon's Lair"), loc("The Slaughter"), loc("Kill the aliens!"), 1, 2000)
+end
+
+function SkipKilledAnim()
+ AnimSetGearPosition(native, unpack(secondPos[1]))
+ AnimSwitchHog(native)
+ AnimWait(native, 1)
+end
+
+function AfterKilledAnim()
+ HideHedge(cyborg)
+ TurnTimeLeft = TurnTime
+ SetGearMessage(native, 0)
+ AddAmmo(native, amPortalGun, 100)
+ SpawnUtilityCrate(2259, 755, amTeleport, 2)
+ SpawnHealthCrate(secondPos[1][1] + 30, secondPos[1][2])
+ ShowMission(loc("Dragon's Lair"), loc("The what?!"), loc("Use the portal gun to get to the next crate, then use the new gun to get to the final destination!|")..
+ loc("Portal hint: one goes to the destination, and one is the entrance.|")..
+ loc("Teleport hint: just use the mouse to select the destination!"), 1, 0)
+end
+-----------------------------Events------------------------------------
+
+function CheckCyborgsDead()
+ return cyborgsLeft == 0
+end
+
+function NullifyAmmo()
+ AddAmmo(native, amRope, 0)
+ AddAmmo(native, amGirder, 0)
+ AddAmmo(native, amLowGravity, 0)
+ AddAmmo(native, amBazooka, 0)
+ AddAmmo(native, amSniperRifle, 0)
+ AddAmmo(native, amDEagle, 0)
+ AddAmmo(native, amDynamite, 0)
+ AddAmmo(native, amFirePunch, 0)
+ AddAmmo(native, amBaseballBat, 0)
+ AddAmmo(native, amMortar, 0)
+ AddAmmo(native, amSnowball, 0)
+ AddAmmo(native, amShotgun, 0)
+end
+
+function DoCyborgsDead()
+ NullifyAmmo()
+ RestoreHedge(cyborg)
+ SetupKilledAnim()
+ SetGearMessage(CurrentHedgehog, 0)
+ AddAnim(killedAnim)
+ AddFunction({func = AfterKilledAnim, args = {}})
+end
+
+
+function PutWeaponCrates()
+ for i = 1, 8 do
+ cratesNum = cratesNum + 1
+ crates[cratesNum] = SpawnAmmoCrate(unpack(cratePos[cratesNum]))
+ end
+ FollowGear(native)
+end
+
+function DoCratesTaken()
+ SetupKillAnim()
+ SetGearMessage(CurrentHedgehog, 0)
+ AddAnim(killAnim)
+ AddFunction({func = AfterKillAnim, args = {}})
+end
+
+function PutCrates(index)
+ if index <= 7 then
+ cratesNum = cratesNum + 1
+ crates[cratesNum] = SpawnUtilityCrate(unpack(cratePos[cratesNum]))
+ AddNewEvent(CheckGearDead, {crates[cratesNum]}, PutCrates, {index + 1}, 0)
+ FollowGear(native)
+ else
+ AddEvent(StoppedGear, {native}, DoCratesTaken, {}, 0)
+ end
+ if index == 4 then
+ AnimSay(native, loc("I'm a ninja."), SAY_THINK, 0)
+ end
+end
+
+function CheckMissionFinished()
+ return gearDead[jetCrate] == true
+end
+
+function DoMissionFinished()
+ AddCaption(loc("Salvation was one step closer now..."))
+ if progress and progress<6 then
+ SaveCampaignVar("Progress", "6")
+ end
+ RestoreHedge(cyborg)
+ DeleteGear(cyborg)
+ TurnTimeLeft = 0
+end
+
+function CheckGearsDead(gearList)
+ for i = 1, # gearList do
+ if gearDead[gearList[i]] ~= true then
+ return false
+ end
+ end
+ return true
+end
+
+
+function CheckGearDead(gear)
+ return gearDead[gear]
+end
+
+function EndMission()
+ RestoreHedge(cyborg)
+ DeleteGear(cyborg)
+ TurnTimeLeft = 0
+end
+
+function CheckFreshDead()
+ return freshDead ~= nil
+end
+
+function CyborgDeadReact()
+ freshDead = nil
+ if cyborgsLeft == 0 then
+ return
+ end
+ AnimSay(native, reactions[cyborgsLeft])
+end
+-----------------------------Misc--------------------------------------
+function HideHedge(hedge)
+ if hedgeHidden[hedge] ~= true then
+ HideHog(hedge)
+ hedgeHidden[hedge] = true
+ end
+end
+
+function RestoreHedge(hedge)
+ if hedgeHidden[hedge] == true then
+ RestoreHog(hedge)
+ hedgeHidden[hedge] = false
+ end
+end
+
+function GetVariables()
+ progress = tonumber(GetCampaignVar("Progress"))
+ m5DeployedNum = tonumber(GetCampaignVar("M5DeployedNum"))
+end
+
+function SetupPlace()
+ for i = 1, 7 do
+ if i ~= m5DeployedNum then
+ DeleteGear(natives[i])
+ else
+ native = natives[i]
+ end
+ end
+ HideHedge(cyborg)
+ jetCrate = SpawnUtilityCrate(3915, 1723, amJetpack)
+
+ SetTimer(AddGear(1071, 1913, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(1098, 1919, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(1136, 1923, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(1170, 1930, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(1203, 1924, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(1228, 1939, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(1264, 1931, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(1309, 1938, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(1352, 1936, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(1386, 1939, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(1432, 1942, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(1483, 1950, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(1530, 1954, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(1579, 1959, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(1000, 1903, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(957, 1903, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(909, 1910, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(889, 1917, gtMine, 0, 0, 0, 0), 5000)
+ ------ STICKY MINE LIST ------
+ tempG = AddGear(1199, 733, gtSMine, 0, 0, 0, 0)
+ tempG = AddGear(1195, 793, gtSMine, 0, 0, 0, 0)
+ tempG = AddGear(1201, 861, gtSMine, 0, 0, 0, 0)
+ tempG = AddGear(682, 878, gtSMine, 0, 0, 0, 0)
+ tempG = AddGear(789, 876, gtSMine, 0, 0, 0, 0)
+end
+
+function SetupEvents()
+ AddNewEvent(CheckMissionFinished, {}, DoMissionFinished, {}, 0)
+ AddNewEvent(CheckGearDead, {native}, EndMission, {}, 0)
+ AddNewEvent(CheckFreshDead, {}, CyborgDeadReact, {}, 1)
+end
+
+function SetupAmmo()
+ AddAmmo(cyborgs[1], amBazooka, 100)
+-- AddAmmo(cyborgs[1], amSniperRifle, 100)
+ AddAmmo(cyborgs[1], amShotgun, 100)
+ AddAmmo(cyborgs[1], amSwitch, 100)
+end
+
+function AddHogs()
+ AddTeam(loc("Natives"), 29439, "Bone", "Island", "HillBilly", "cm_birdy")
+ for i = 1, 7 do
+ natives[i] = AddHog(nativeNames[i], 0, 200, nativeHats[i])
+ gearDead[natives[i]] = false
+ end
+
+ AddTeam(loc("011101001"), 14483456, "ring", "UFO", "Robot", "cm_star")
+ cyborg = AddHog(loc("Unit 334a$7%;.*"), 0, 200, "cyborg1")
+ gearDead[cyborg] = false
+
+ AddTeam(loc("011101000"), 14483455, "ring", "UFO", "Robot", "cm_star")
+ for i = 1, 4 do
+ cyborgs[i] = AddHog(cyborgNames[i], 2, 100, "cyborg2")
+ gearDead[cyborgs[i]] = false
+ end
+ cyborgsLeft = 4
+
+ for i = 1, 7 do
+ AnimSetGearPosition(natives[i], unpack(nativePos))
+ end
+
+ AnimSetGearPosition(cyborg, unpack(cyborgPos))
+
+ for i = 1, 4 do
+ AnimSetGearPosition(cyborgs[i], unpack(cyborgsPos[i]))
+ AnimTurn(cyborgs[i], cyborgsDir[i])
+ end
+
+end
+
+function CondNeedToTurn(hog1, hog2)
+ xl, xd = GetX(hog1), GetX(hog2)
+ if xl > xd then
+ AnimInsertStepNext({func = AnimTurn, args = {hog1, "Left"}})
+ AnimInsertStepNext({func = AnimTurn, args = {hog2, "Right"}})
+ elseif xl < xd then
+ AnimInsertStepNext({func = AnimTurn, args = {hog2, "Left"}})
+ AnimInsertStepNext({func = AnimTurn, args = {hog1, "Right"}})
+ end
+end
+
+-----------------------------Main Functions----------------------------
+
+function onGameInit()
+ Seed = 0
+ GameFlags = gfSolidLand + gfDisableLandObjects + gfDisableWind + gfDisableGirders
+ TurnTime = 60000
+ CaseFreq = 0
+ MinesNum = 20
+ MinesTime = 3000
+ Explosives = 6
+ Delay = 10
+ MapGen = 2
+ Theme = "City"
+ SuddenDeathTurns = 25
+
+ for i = 1, #map do
+ ParseCommand('draw ' .. map[i])
+ end
+
+ AddHogs()
+ AnimInit()
+end
+
+function onGameStart()
+ GetVariables()
+ SetupAmmo()
+ SetupPlace()
+ AnimationSetup()
+ SetupEvents()
+ AddAnim(startAnim)
+ AddFunction({func = AfterStartAnim, args = {}})
+ ShowMission(loc("Dragon's Lair"), loc("Y Chwiliad"), loc("Find your tribe!|Cross the lake!"), 1, 0)
+end
+
+function onGameTick()
+ AnimUnWait()
+ if ShowAnimation() == false then
+ return
+ end
+ ExecuteAfterAnimations()
+ CheckEvents()
+end
+
+function onGearDelete(gear)
+ gearDead[gear] = true
+ if GetGearType(gear) == gtHedgehog then
+ if GetHogTeamName(gear) == loc("011101000") then
+ freshDead = GetHogName(gear)
+ cyborgsLeft = cyborgsLeft - 1
+ end
+ end
+end
+
+function onAmmoStoreInit()
+ SetAmmo(amFirePunch, 3, 0, 0, 0)
+ SetAmmo(amBaseballBat, 2, 0, 0, 0)
+ SetAmmo(amGirder, 0, 0, 0, 2)
+ SetAmmo(amLowGravity, 0, 0, 0, 1)
+ SetAmmo(amSkip, 9, 0, 0, 0)
+end
+
+function onNewTurn()
+ if AnimInProgress() then
+ TurnTimeLeft = -1
+ return
+ end
+ if GetHogTeamName(CurrentHedgehog) == loc("011101000") then
+ SetInputMask(band(0xFFFFFFFF, bnot(gmLeft + gmRight + gmLJump + gmHJump)))
+ for i = 1, 4 do
+ if gearDead[CurrentHedgehog] ~= true and gearDead[native] ~= true then
+ if gearDead[cyborgs[i]] ~= true and GetX(cyborgs[i]) < GetX(native) then
+ HogTurnLeft(cyborgs[i], false)
+ else
+ HogTurnLeft(cyborgs[i], true)
+ end
+ end
+ end
+ if TotalRounds % 6 == 0 then
+ AddAmmo(CurrentHedgehog, amSniperRifle, 1)
+ AddAmmo(CurrentHedgehog, amDEagle, 1)
+ end
+ TurnTimeLeft = 30000
+ elseif GetHogTeamName(CurrentHedgehog) == loc("011101001") then
+ TurnTimeLeft = 0
+ else
+ SetInputMask(0xFFFFFFFF)
+ AddCaption(loc("Turns until Sudden Death: ") .. SuddenDeathTurns - TotalRounds)
+ end
+end
+
+function onPrecise()
+ if GameTime > 2500 and AnimInProgress() then
+ SetAnimSkip(true)
+ end
+ if AnimInProgress() == false then
+ end
+end
+
+function onPreciseUp()
+end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Missions/Campaign/A_Classic_Fairytale/enemy.lua Mon Jul 01 23:23:22 2013 +0300
@@ -0,0 +1,666 @@
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Animate.lua")
+
+
+--------------------------------------------Constants------------------------------------
+choiceAccepted = 1
+choiceRefused = 2
+choiceAttacked = 3
+
+choiceEliminate = 1
+choiceSpare = 2
+
+leaksNum = 1
+denseNum = 2
+waterNum = 3
+buffaloNum = 4
+chiefNum = 5
+girlNum = 6
+wiseNum = 7
+ramonNum = 8
+spikyNum = 9
+
+denseScene = 1
+princessScene = 2
+waterScene = 3
+cyborgScene = 4
+
+nativeNames = {loc("Leaks A Lot"), loc("Dense Cloud"), loc("Fiery Water"),
+ loc("Raging Buffalo"), loc("Righteous Beard"), loc("Fell From Grace"),
+ loc("Wise Oak"), loc("Ramon"), loc("Spiky Cheese")
+ }
+
+nativeHats = {"Rambo", "RobinHood", "pirate_jack", "zoo_Bunny", "IndianChief",
+ "tiara", "AkuAku", "rasta", "hair_yellow"}
+
+nativePos = {{1259, 120}, {2378, 796}, {424, 1299}, {3322, 260}, {1022, 1550}}
+nativeDir = {"Right", "Left", "Right", "Left", "Right"}
+
+cannibalNames = {loc("Honest Lee"), loc("Vegan Jack"), loc("Sirius Lee"),
+ loc("Brutal Lily")}
+cannibalPos = {{162, 266}, {2159, 1517}, {3311, 1621}, {1180, 1560}}
+cannibalDir = {"Right", "Left", "Left", "Right"}
+cannibalsNum = 4
+
+playersDir = {"Right", "Left", "Right", "Left", "Right", "Right", "Left", "Left", "Right"}
+playersAntiDir = {"Left", "Right", "Left", "Right", "Left", "Left", "Right", "Right", "Left"}
+
+cyborgNames = {loc("Smith 0.97"), loc("Smith 0.98"), loc("Smith 0.99a"),
+ loc("Smith 0.99b"), loc("Smith 0.99f"), loc("Smith 1.0")}
+cyborgPos = {{2162, 20}, {2458, 564}, {542, 1133}, {3334, 1427}}
+cyborgDir = "Right"
+cyborgsNum = 6
+cyborgsPos = {{1490, 330}, {1737, 1005}, {2972, 922}, {1341, 1571},
+ {751, 543}, {3889, 907}}
+cyborgsDir = {"Right", "Right", "Left", "Right", "Right", "Left"}
+
+leaderPos = {3474, 151}
+leaderDir = "Left"
+
+-----------------------------Variables---------------------------------
+natives = {}
+origNatives = {}
+
+cyborgs = {}
+cyborg = nil
+
+cannibals = {}
+players = {}
+leader = nil
+
+gearDead = {}
+hedgeHidden = {}
+
+startAnim = {}
+finalAnim = {}
+-----------------------------Animations--------------------------------
+function CondNeedToTurn(hog1, hog2)
+ xl, xd = GetX(hog1), GetX(hog2)
+ if xl > xd then
+ AnimInsertStepNext({func = AnimTurn, args = {hog1, "Left"}})
+ AnimInsertStepNext({func = AnimTurn, args = {hog2, "Right"}})
+ elseif xl < xd then
+ AnimInsertStepNext({func = AnimTurn, args = {hog2, "Left"}})
+ AnimInsertStepNext({func = AnimTurn, args = {hog1, "Right"}})
+ end
+end
+
+function CondNeedToTurn2(hog1, hog2)
+ xl, xd = GetX(hog1), GetX(hog2)
+ if xl > xd then
+ AnimTurn(hog1, "Left")
+ AnimTurn(hog2, "Right")
+ elseif xl < xd then
+ AnimTurn(hog2, "Left")
+ AnimTurn(hog1, "Right")
+ end
+end
+
+function EmitDenseClouds(dir)
+ local dif
+ if dir == "Left" then
+ dif = 10
+ else
+ dif = -10
+ end
+ if dir == nil then
+ dx, dy = GetGearVelocity(dense)
+ if dx < 0 then
+ dif = 10
+ else
+ dif = -10
+ end
+ end
+ AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
+ AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
+ AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
+ AnimInsertStepNext({func = AnimWait, args = {dense, 800}})
+ AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
+ AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
+ AnimInsertStepNext({func = AnimWait, args = {dense, 800}})
+ AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
+end
+
+function RestoreNatives(cgi)
+ for i = 1, playersNum do
+ RestoreHedge(players[i])
+ AnimOutOfNowhere(players[i], GetGearPosition(players[i]))
+ end
+end
+
+function AnimationSetup()
+ SetupCyborgStartAnim()
+ SetupPeopleStartAnim()
+ SetupEnemyStartAnim()
+ AddSkipFunction(startAnim, SkipStartAnim, {})
+end
+
+function SetupCyborgStartAnim()
+ table.insert(startAnim, {func = AnimWait, args = {cyborg, 3000}})
+ table.insert(startAnim, {func = AnimTurn, args = {cyborg, "Left"}})
+ table.insert(startAnim, {func = AnimWait, args = {cyborg, 800}})
+ table.insert(startAnim, {func = AnimTurn, args = {cyborg, "Right"}})
+ table.insert(startAnim, {func = AnimWait, args = {cyborg, 800}})
+ table.insert(startAnim, {func = AnimTurn, args = {cyborg, "Left"}})
+ table.insert(startAnim, {func = AnimWait, args = {cyborg, 800}})
+ table.insert(startAnim, {func = AnimTeleportGear, args = {cyborg, unpack(cyborgPos[2])}})
+ table.insert(startAnim, {func = AnimWait, args = {cyborg, 800}})
+ table.insert(startAnim, {func = AnimTurn, args = {cyborg, "Right"}})
+ table.insert(startAnim, {func = AnimWait, args = {cyborg, 800}})
+ table.insert(startAnim, {func = AnimTurn, args = {cyborg, "Left"}})
+ table.insert(startAnim, {func = AnimWait, args = {cyborg, 800}})
+ table.insert(startAnim, {func = AnimTeleportGear, args = {cyborg, unpack(cyborgPos[3])}})
+ table.insert(startAnim, {func = AnimWait, args = {cyborg, 1800}})
+ table.insert(startAnim, {func = AnimTeleportGear, args = {cyborg, unpack(cyborgPos[4])}})
+ table.insert(startAnim, {func = AnimWait, args = {cyborg, 800}})
+ table.insert(startAnim, {func = AnimSay, args = {cyborg, loc("Everything looks OK..."), SAY_THINK, 2500}})
+ table.insert(startAnim, {func = AnimSay, args = {cyborg, loc("This will be fun!"), SAY_THINK, 2500}})
+ table.insert(startAnim, {func = AnimJump, args = {cyborg, "high"}})
+ table.insert(startAnim, {func = AnimCustomFunction, args = {cyborg, RestoreNatives, {true}}})
+ table.insert(startAnim, {func = AnimSay, args = {cyborg, loc("HAHA!"), SAY_SHOUT, 2000}})
+ table.insert(startAnim, {func = AnimSwitchHog, args = {players[1]}})
+ table.insert(startAnim, {func = AnimDisappear, swh = false, args = {cyborg, unpack(cyborgPos[4])}})
+ table.insert(startAnim, {func = HideHedge, swh = false, args = {cyborg}})
+end
+
+function SetupPeopleStartAnim()
+ for i = 1, playersNum do
+ table.insert(startAnim, {func = AnimTurn, swh = false, args = {players[i], playersAntiDir[i]}})
+ end
+ table.insert(startAnim, {func = AnimWait, args = {players[1], 800}})
+ for i = 1, playersNum do
+ table.insert(startAnim, {func = AnimTurn, swh = false, args = {players[i], playersDir[i]}})
+ end
+ table.insert(startAnim, {func = AnimWait, args = {players[1], 800}})
+ table.insert(startAnim, {func = AnimSay, args = {players[1], loc("What is this place?"), SAY_SHOUT, 2500}})
+ if m5LeaksDead == 1 then
+ table.insert(startAnim, {func = AnimSay, args = {players[1], loc("And how am I alive?!"), SAY_SAY, 3000}})
+ end
+ table.insert(startAnim, {func = AnimCustomFunction, args = {players[1], CondNeedToTurn, {players[1], players[2]}}})
+ table.insert(startAnim, {func = AnimSay, args = {players[2], loc("It must be the cyborgs again!"), SAY_SAY, 4000}})
+ table.insert(startAnim, {func = AnimSay, args = {players[3], loc("Looks like the whole world is falling apart!"), SAY_SAY, 6000}})
+ table.insert(startAnim, {func = AnimSay, args = {cannibals[1], loc("Look out! We're surrounded by cannibals!"), SAY_SHOUT, 6000}})
+ table.insert(startAnim, {func = AnimCustomFunction, args = {players[4], CondNeedToTurn, {players[4], cannibals[1]}}})
+ table.insert(startAnim, {func = AnimCustomFunction, args = {players[4], CondNeedToTurn, {players[1], cannibals[1]}}})
+ table.insert(startAnim, {func = AnimSay, args = {players[4], loc("Cannibals?! You're the cannibals!"), SAY_SHOUT, 4000}})
+ table.insert(startAnim, {func = AnimSay, args = {cannibals[1], loc("WHAT?! You're the ones attacking us!"), SAY_SHOUT, 5000}})
+ table.insert(startAnim, {func = AnimSay, args = {players[4], loc("You have kidnapped our whole tribe!"), SAY_SHOUT, 4000}})
+ table.insert(startAnim, {func = AnimSay, args = {players[1], loc("You've been assaulting us, we have been just defending ourselves!"), SAY_SHOUT, 8000}})
+ table.insert(startAnim, {func = AnimSay, args = {cannibals[1], loc("I can't believe this!"), SAY_SHOUT, 3000}})
+ table.insert(startAnim, {func = AnimSay, args = {cannibals[1], loc("Have we ever attacked you first?"), SAY_SHOUT, 5000}})
+ table.insert(startAnim, {func = AnimSay, args = {players[4], loc("Yes!"), SAY_SHOUT, 2000}})
+ table.insert(startAnim, {func = AnimSay, args = {cannibals[1], loc("When?"), SAY_SHOUT, 2000}})
+ table.insert(startAnim, {func = AnimSay, args = {players[4], loc("Uhmm...ok no."), SAY_SHOUT, 2000}})
+ table.insert(startAnim, {func = AnimSay, args = {players[1], loc("But you're cannibals. It's what you do."), SAY_SHOUT, 5000}})
+ table.insert(startAnim, {func = AnimSay, args = {cannibals[1], loc("Again with the 'cannibals' thing!"), SAY_SHOUT, 4000}})
+ table.insert(startAnim, {func = AnimSay, args = {cannibals[1], loc("Where do you get that?!"), SAY_SHOUT, 3000}})
+ table.insert(startAnim, {func = AnimSay, args = {players[4], loc("Everyone knows this."), SAY_SHOUT, 2500}})
+ table.insert(startAnim, {func = AnimSay, args = {players[1], loc("I didn't until about a month ago."), SAY_SHOUT, 4000}})
+ table.insert(startAnim, {func = AnimSay, args = {players[4], loc("Hmmm...actually...I didn't either."), SAY_SHOUT, 4000}})
+ table.insert(startAnim, {func = AnimSay, args = {cannibals[1], loc("About a month ago, a cyborg came and told us that you're the cannibals!"), SAY_SHOUT, 8000}})
+ table.insert(startAnim, {func = AnimSay, args = {players[1], loc("A cy-what?"), SAY_SHOUT, 2000}})
+ table.insert(startAnim, {func = AnimSay, args = {cannibals[1], loc("Cyborg. It's what the aliens call themselves."), SAY_SHOUT, 5000}})
+ table.insert(startAnim, {func = AnimSay, args = {cannibals[1], loc("They told us to wear these clothes. They said that this is the newest trend."), SAY_SHOUT, 8000}})
+ table.insert(startAnim, {func = AnimSay, args = {players[1], loc("They've been manipulating us all this time!"), SAY_SHOUT, 5000}})
+ table.insert(startAnim, {func = AnimSay, args = {cannibals[1], loc("They must be trying to weaken us!"), SAY_SHOUT, 5000}})
+ table.insert(startAnim, {func = AnimSay, args = {players[1], loc("We have to unite and defeat those cylergs!"), SAY_SHOUT, 5000}})
+ table.insert(startAnim, {func = AnimSay, args = {cannibals[1], loc("We can't let them take over our little island!"), SAY_SHOUT, 5000}})
+end
+
+function RestoreCyborgs(cgi)
+ if cyborgsRestored == true then
+ return
+ end
+ for i = 1, cyborgsNum do
+ RestoreHedge(cyborgs[i])
+ if cgi == true then
+ AnimOutOfNowhere(cyborgs[i], unpack(cyborgsPos[i]))
+ end
+ end
+ RestoreHedge(leader)
+ AnimOutOfNowhere(leader, unpack(leaderPos))
+ cyborgsRestored = true
+end
+
+function SetupEnemyStartAnim()
+ local gear
+ table.insert(startAnim, {func = AnimCustomFunction, args = {cannibals[1], RestoreCyborgs, {true}}})
+ if m8EnemyFled == 1 then
+ gear = leader
+ else
+ gear = cyborgs[2]
+ end
+ table.insert(startAnim, {func = AnimCustomFunction, args = {players[1], CondNeedToTurn, {players[4], gear}}})
+ table.insert(startAnim, {func = AnimCustomFunction, args = {players[1], CondNeedToTurn, {players[1], gear}}})
+ table.insert(startAnim, {func = AnimSay, args = {gear, loc("You have finally figured it out!"), SAY_SHOUT, 4500}})
+ table.insert(startAnim, {func = AnimSay, args = {gear, loc("You meatbags are pretty slow, you know!"), SAY_SHOUT, 5500}})
+ table.insert(startAnim, {func = AnimSay, args = {players[1], loc("Why do you want to take over our island?"), SAY_SHOUT, 5500}})
+ table.insert(startAnim, {func = AnimSay, args = {gear, loc("Do you have any idea how valuable grass is?"), SAY_SHOUT, 5500}})
+ table.insert(startAnim, {func = AnimSay, args = {gear, loc("This island is the only place left on Earth with grass on it!"), SAY_SHOUT, 7000}})
+ table.insert(startAnim, {func = AnimSay, args = {gear, loc("It's worth more than wood!"), SAY_SHOUT, 4000}})
+ table.insert(startAnim, {func = AnimSay, args = {gear, loc("That makes it almost invaluable!"), SAY_SHOUT, 4500}})
+ table.insert(startAnim, {func = AnimSay, args = {players[1], loc("We have nowhere else to live!"), SAY_SHOUT, 4500}})
+ table.insert(startAnim, {func = AnimSay, args = {gear, loc("That's not our problem!"), SAY_SHOUT, 4500}})
+ table.insert(startAnim, {func = AnimSay, args = {players[1], loc("We'll give you a problem then!"), SAY_SHOUT, 5000}})
+ table.insert(startAnim, {func = AnimSwitchHog, args = {gear}})
+end
+
+function SetupFinalAnim()
+ finalAnim = {
+ {func = AnimGearWait, args = {cyborg, 1000}},
+ {func = AnimSay, args = {cyborg, loc("Nicely done, meatbags!"), SAY_SAY, 3000}},
+ {func = AnimSay, args = {cyborg, loc("You have won the game by proving true cooperative skills!"), SAY_SAY, 7000}},
+ {func = AnimSay, args = {cyborg, loc("You have proven yourselves worthy!"), SAY_SAY, 4000}},
+ {func = AnimSay, args = {players[1], loc("Game? Was this a game to you?!"), SAY_SAY, 4000}},
+ {func = AnimSay, args = {cyborg, loc("Well, yes. This was a cyborg television show."), SAY_SAY, 5500}},
+ {func = AnimSay, args = {cyborg, loc("It is called 'Hogs of Steel'."), SAY_SAY, 4000}},
+ {func = AnimSay, args = {players[1], loc("Are you saying that many of us have died for your entertainment?"), SAY_SAY, 8000}},
+ {func = AnimSay, args = {players[1], loc("Our tribe, our beautiful island!"), SAY_SAY, 4000}},
+ {func = AnimSay, args = {players[1], loc("All gone...everything!"), SAY_SAY, 3000}},
+ {func = AnimSay, args = {cyborg, loc("But the ones alive are stronger in their heart!"), SAY_SAY, 6000}},
+ {func = AnimSay, args = {cyborg, loc("Just kidding, none of you have died!"), SAY_SAY, 5000}},
+ {func = AnimSay, args = {cyborg, loc("I mean, none of you ceased to live."), SAY_SAY, 5000}},
+ {func = AnimSay, args = {cyborg, loc("You'll see what I mean!"), SAY_SAY, 4000}},
+ {func = AnimSay, args = {cyborg, loc("They are all waiting back in the village, haha."), SAY_SAY, 7000}},
+ {func = AnimSay, args = {players[1], loc("You are playing with our lives here!"), SAY_SAY, 6000}},
+ {func = AnimSay, args = {players[1], loc("Do you think you're some kind of god?"), SAY_SAY, 6000}},
+ {func = AnimSay, args = {cyborg, loc("Interesting idea, haha!"), SAY_SAY, 2000}},
+ {func = AnimSwitchHog, args = {players[1]}},
+ {func = AnimWait, args = {players[1], 1}},
+ {func = AnimDisappear, swh = false, args = {cyborg, unpack(cyborgPos[4])}},
+ {func = HideHedge, swh = false, args = {cyborg}},
+ {func = AnimSay, args = {players[1], loc("What a douche!"), SAY_SAY, 2000}},
+ }
+end
+--------------------------Anim skip functions--------------------------
+function SkipStartAnim()
+ RestoreNatives()
+ RestoreCyborgs()
+ SetGearMessage(CurrentHedgehog, 0)
+ AnimSwitchHog(cyborgs[1])
+ AnimWait(cyborg, 1)
+ AddFunction({func = HideHedge, args = {cyborg}})
+end
+
+function AfterStartAnim()
+ ShowMission(loc("The Enemy Of My Enemy"), loc("The Union"), loc("Defeat the cyborgs!"), 1, 0)
+ PutWeaponCrates()
+ PutHealthCrates()
+ TurnTimeLeft = 0
+end
+
+function PutHealthCrates()
+ for i = 1, 10 do
+ SpawnHealthCrate(0, 0)
+ end
+end
+
+function PutWeaponCrates()
+ SpawnAmmoCrate(2399, 622, amNapalm, 2)
+ SpawnAmmoCrate(2199, -18, amBee, 2)
+ SpawnAmmoCrate(2088, 430, amBee, 2)
+ SpawnAmmoCrate(237, 20, amMortar, 4)
+ SpawnAmmoCrate(312, 1107, amMolotov, 3)
+ SpawnAmmoCrate(531, 1123, amWatermelon, 2)
+ SpawnAmmoCrate(1253, 1444, amFlamethrower, 5)
+ SpawnAmmoCrate(994, 1364, amBaseballBat, 3)
+ SpawnAmmoCrate(1104, 1553, amMine, 6)
+ SpawnAmmoCrate(2277, 803, amDynamite, 2)
+ SpawnAmmoCrate(1106, 184, amRCPlane, 3)
+ SpawnAmmoCrate(1333, 28, amSMine, 4)
+ SpawnAmmoCrate(90, 279, amAirAttack, 2)
+ SpawnAmmoCrate(288, 269, amBee, 2)
+ SpawnAmmoCrate(818, 1633, amBaseballBat, 2)
+end
+-----------------------------Events------------------------------------
+function CheckNativesDead()
+ return nativesLeft == 0
+end
+
+function CheckCannibalsDead()
+ return cannibalsLeft == 0
+end
+
+function CheckPlayersDead()
+ return playersLeft == 0
+end
+
+function CheckCyborgsDead()
+ return (cyborgsLeft == 0 and (leader == nil or gearDead[leader] == true))
+end
+
+function DoNativesDead()
+ nativesDeadFresh = true
+ TurnTimeLeft = 0
+end
+
+function DoCannibalsDead()
+ cannibalsDeadFresh = true
+ TurnTimeLeft = 0
+end
+
+function DoPlayersDead()
+ RemoveEventFunc(CheckNativesDead)
+ RemoveEventFunc(CheckCannibalsDead)
+ RemoveEventFunc(CheckCyborgsDead)
+ playersDeadFresh = true
+ TurnTimeLeft = 0
+end
+
+function DoCyborgsDead()
+-- RemoveEventFunc(CheckNativesDead)
+-- RemoveEventFunc(CheckCannibalsDead)
+ cyborgsDeadFresh= true
+ TurnTimeLeft = 0
+end
+
+function CheckGearsDead(gearList)
+ for i = 1, # gearList do
+ if gearDead[gearList[i]] ~= true then
+ return false
+ end
+ end
+ return true
+end
+
+function CheckGearDead(gear)
+ return gearDead[gear]
+end
+
+function FailedMission()
+ RestoreHedge(cyborg)
+ AnimOutOfNowhere(cyborg, unpack(cyborgPos[1]))
+ if CheckCyborgsDead() then
+ AnimSay(cyborg, loc("Hmmm...it's a draw. How unfortunate!"), SAY_THINK, 6000)
+ elseif leader ~= nil then
+ CondNeedToTurn2(cyborg, leader)
+ AddAnim({{func = AnimSay, args = {leader, loc("Yay, we won!"), SAY_SAY, 2000}},
+ {func = AnimSay, args = {cyborg, loc("Nice work!"), SAY_SAY, 2000}}})
+ else
+ CondNeedToTurn2(cyborg, cyborgs[1])
+ AddAnim({{func = AnimSay, args = {cyborgs[1], loc("Yay, we won!"), SAY_SAY, 2000}},
+ {func = AnimSay, args = {cyborg, loc("Nice work!"), SAY_SAY, 2000}}})
+ end
+ AddFunction({func = LoseMission, args = {}})
+end
+
+function LoseMission()
+ ParseCommand("teamgone " .. loc("Natives"))
+ ParseCommand("teamgone " .. loc("Cannibals"))
+ ParseCommand("teamgone " .. loc("011101001"))
+ TurnTimeLeft = 0
+end
+
+function WonMission()
+ RestoreHedge(cyborg)
+ CondNeedToTurn2(cyborg, players[1])
+ SetupFinalAnim()
+ AddAnim(finalAnim)
+ AddFunction({func = WinMission, args = {}})
+end
+
+function WinMission()
+ if progress and progress<9 then
+ SaveCampaignVar("Progress", "9")
+ end
+ ParseCommand("teamgone " .. loc("011101001"))
+ TurnTimeLeft = 0
+end
+-----------------------------Misc--------------------------------------
+function HideHedge(hedge)
+ if hedgeHidden[hedge] ~= true then
+ HideHog(hedge)
+ hedgeHidden[hedge] = true
+ end
+end
+
+function RestoreHedge(hedge)
+ if hedgeHidden[hedge] == true then
+ RestoreHog(hedge)
+ hedgeHidden[hedge] = false
+ end
+end
+
+function GetVariables()
+ progress = tonumber(GetCampaignVar("Progress"))
+ m5DeployedNum = tonumber(GetCampaignVar("M5DeployedNum"))
+ m2Choice = tonumber(GetCampaignVar("M2Choice"))
+ m5Choice = tonumber(GetCampaignVar("M5Choice"))
+ m2DenseDead = tonumber(GetCampaignVar("M2DenseDead"))
+ m4DenseDead = tonumber(GetCampaignVar("M4DenseDead"))
+ m5DenseDead = tonumber(GetCampaignVar("M5DenseDead"))
+ m4LeaksDead = tonumber(GetCampaignVar("M4LeaksDead"))
+ m5LeaksDead = tonumber(GetCampaignVar("M5LeaksDead"))
+ m4ChiefDead = tonumber(GetCampaignVar("M4ChiefDead"))
+ m5ChiefDead = tonumber(GetCampaignVar("M5ChiefDead"))
+ m4WaterDead = tonumber(GetCampaignVar("M4WaterDead"))
+ m5WaterDead = tonumber(GetCampaignVar("M5WaterDead"))
+ m4BuffaloDead = tonumber(GetCampaignVar("M4BuffaloDead"))
+ m5BuffaloDead = tonumber(GetCampaignVar("M5BuffaloDead"))
+ m5WiseDead = tonumber(GetCampaignVar("M5WiseDead"))
+ m5GirlDead = tonumber(GetCampaignVar("M5GirlDead"))
+ m8DeployedDead = tonumber(GetCampaignVar("M8DeployedDead"))
+ m8PrincessDead = tonumber(GetCampaignVar("M8PrincessDead"))
+ m8RamonDead = tonumber(GetCampaignVar("M8RamonDead"))
+ m8SpikyDead = tonumber(GetCampaignVar("M8SpikyDead"))
+ m8DeployedLeader = tonumber(GetCampaignVar("M8DeployedLeader"))
+ m8PrincessLeader = tonumber(GetCampaignVar("M8PrincessLeader"))
+ m8EnemyFled = tonumber(GetCampaignVar("M8EnemyFled"))
+ m8Scene = tonumber(GetCampaignVar("M8Scene"))
+end
+
+function SetupPlace()
+ for i = 1, playersNum do
+ HideHedge(players[i])
+ end
+ for i = 1, cyborgsNum do
+ HideHedge(cyborgs[i])
+ end
+ if leader ~= nil then
+ HideHedge(leader)
+ end
+end
+
+function SetupEvents()
+ AddNewEvent(CheckPlayersDead, {}, DoPlayersDead, {}, 0)
+ AddNewEvent(CheckNativesDead, {}, DoNativesDead, {}, 0)
+ AddNewEvent(CheckCannibalsDead, {}, DoCannibalsDead, {}, 0)
+ AddNewEvent(CheckCyborgsDead, {}, DoCyborgsDead, {}, 0)
+end
+
+function SetupAmmo()
+ AddAmmo(cyborgs[1], amClusterBomb, 100)
+ AddAmmo(cyborgs[1], amMortar, 100)
+ AddAmmo(cyborgs[1], amDynamite, 2)
+ AddAmmo(cyborgs[1], amAirAttack, 2)
+ AddAmmo(cyborgs[1], amTeleport, 100)
+
+ if leader ~= nil then
+ AddAmmo(leader, amClusterBomb, 100)
+ AddAmmo(leader, amMortar, 100)
+ AddAmmo(leader, amDynamite, 100)
+ AddAmmo(leader, amAirAttack, 3)
+ AddAmmo(leader, amTeleport, 100)
+ end
+end
+
+function AddHogs()
+ AddTeam(loc("011101001"), 14483456, "ring", "UFO", "Robot", "cm_star")
+ cyborg = AddHog(loc("Unit 334a$7%;.*"), 0, 200, "cyborg1")
+
+ AddTeam(loc("Natives"), 29439, "Bone", "Island", "HillBilly", "cm_birdy")
+ natives[1] = AddHog(nativeNames[leaksNum], 0, 100, nativeHats[leaksNum])
+ if m5DeployedNum ~= leaksNum and m8DeployedLeader == 0 then
+ natives[2] = AddHog(nativeNames[m5DeployedNum], 0, 100, nativeHats[m5DeployedNum])
+ end
+ table.insert(natives, AddHog(nativeNames[ramonNum], 0, 100, nativeHats[ramonNum]))
+ table.insert(natives, AddHog(nativeNames[spikyNum], 0, 100, nativeHats[spikyNum]))
+ if m8PrincessLeader == 0 then
+ table.insert(natives, AddHog(loc("Fell From Heaven"), 0, 100, "tiara"))
+ end
+ nativesNum = #natives
+ nativesLeft = nativesNum
+ cannibalsLeft = cannibalsNum
+ for i = 1, nativesNum do
+ table.insert(players, natives[i])
+ end
+
+ AddTeam(loc("Cannibals"), 29439, "Bone", "Island", "HillBilly", "cm_birdy")
+ for i = 1, cannibalsNum do
+ cannibals[i] = AddHog(cannibalNames[i], 0, 100, "Zombi")
+ table.insert(players, cannibals[i])
+ end
+ playersNum = #players
+ playersLeft = playersNum
+
+ AddTeam(loc("Hedge-cogs"), 14483455, "ring", "UFO", "Robot", "cm_star")
+ for i = 1, cyborgsNum do
+ cyborgs[i] = AddHog(cyborgNames[i], 2, 80, "cyborg2")
+ end
+
+ if m8EnemyFled == 1 then
+ AddTeam(loc("Leader"), 14483455, "ring", "UFO", "Robot", "cm_star")
+ if m8Scene == denseScene then
+ leader = AddHog(loc("Dense Cloud"), 2, 200, nativeHats[denseNum])
+ elseif m8Scene == waterScene then
+ leader = AddHog(loc("Fiery Water"), 2, 200, nativeHats[waterNum])
+ elseif m8Scene == princessScene then
+ leader = AddHog(loc("Fell From Heaven"), 2, 200, "tiara")
+ else
+ leader = AddHog(loc("Nancy Screw"), 2, 200, "cyborg2")
+ end
+ end
+
+ cyborgsLeft = cyborgsNum
+
+ for i = 1, nativesNum do
+ AnimSetGearPosition(natives[i], unpack(nativePos[i]))
+ AnimTurn(natives[i], nativeDir[i])
+ end
+ for i = 1, cannibalsNum do
+ AnimSetGearPosition(cannibals[i], unpack(cannibalPos[i]))
+ AnimTurn(cannibals[i], cannibalDir[i])
+ end
+ for i = 1, cyborgsNum do
+ AnimSetGearPosition(cyborgs[i], unpack(cyborgsPos[i]))
+ AnimTurn(cyborgs[i], cyborgsDir[i])
+ end
+ AnimSetGearPosition(cyborg, unpack(cyborgPos[1]))
+ AnimTurn(cyborg, cyborgDir)
+ if leader ~= nil then
+ AnimSetGearPosition(leader, unpack(leaderPos))
+ AnimTurn(leader, leaderDir[i])
+ end
+end
+
+-----------------------------Main Functions----------------------------
+
+function onGameInit()
+ Seed = 0
+ GameFlags = gfSolidLand
+ TurnTime = 60000
+ CaseFreq = 0
+ MinesNum = 0
+ MinesTime = 3000
+ Explosives = 0
+ Delay = 10
+ Map = "Islands"
+ Theme = "EarthRise"
+ SuddenDeathTurns = 20
+
+ GetVariables()
+ AnimInit()
+ AddHogs()
+end
+
+function onGameStart()
+ SetupAmmo()
+ SetupPlace()
+ AnimationSetup()
+ SetupEvents()
+ AddAnim(startAnim)
+ AddFunction({func = AfterStartAnim, args = {}})
+end
+
+function onGameTick()
+ AnimUnWait()
+ if ShowAnimation() == false then
+ return
+ end
+ ExecuteAfterAnimations()
+ CheckEvents()
+end
+
+function onGearDelete(gear)
+ gearDead[gear] = true
+ if GetGearType(gear) == gtHedgehog then
+ if GetHogTeamName(gear) == loc("Natives") then
+ for i = 1, nativesLeft do
+ if natives[i] == gear then
+ table.remove(natives, i)
+ table.remove(players, i)
+ nativesLeft = nativesLeft - 1
+ playersLeft = playersLeft - 1
+ end
+ end
+ elseif GetHogTeamName(gear) == loc("Cannibals") then
+ for i = 1, cannibalsLeft do
+ if cannibals[i] == gear then
+ table.remove(cannibals, i)
+ table.remove(players, nativesLeft + i)
+ cannibalsLeft = cannibalsLeft - 1
+ playersLeft = playersLeft - 1
+ end
+ end
+ elseif GetHogTeamName(gear) == loc("Hedge-cogs") then
+ for i = 1, cyborgsLeft do
+ if cyborgs[i] == gear then
+ table.remove(cyborgs, i)
+ end
+ end
+ cyborgsLeft = cyborgsLeft - 1
+ end
+ end
+end
+
+function onAmmoStoreInit()
+ SetAmmo(amSkip, 9, 0, 0, 0)
+ SetAmmo(amSwitch, 9, 0, 0, 0)
+ SetAmmo(amDEagle, 9, 0, 0, 0)
+ SetAmmo(amSniperRifle, 9, 0, 0, 0)
+ SetAmmo(amBazooka, 8, 0, 0, 0)
+ SetAmmo(amGrenade, 7, 0, 0, 0)
+ SetAmmo(amFirePunch, 9, 0, 0, 0)
+ SetAmmo(amShotgun, 9, 0, 0, 0)
+
+ SetAmmo(amParachute, 9, 0, 0, 0)
+ SetAmmo(amRope, 9, 0, 0, 0)
+ SetAmmo(amPickHammer, 9, 0, 0, 0)
+ SetAmmo(amBlowTorch, 9, 0, 0, 0)
+end
+
+function onNewTurn()
+ if AnimInProgress() then
+ TurnTimeLeft = -1
+ return
+ end
+ if playersDeadFresh then
+ playersDeadFresh = false
+ FailedMission()
+ elseif cyborgsDeadFresh then
+ cyborgsDeadFresh = false
+ WonMission()
+ elseif nativesDeadFresh and GetHogTeamName(CurrentHedgehog) == loc("Cannibals") then
+ AnimSay(CurrentHedgehog, loc("Your deaths will be avenged, cannibals!"), SAY_SHOUT, 0)
+ nativesDeadFresh = false
+ elseif cannibalsDeadFresh and GetHogTeamName(CurrentHedgehog) == loc("Natives") then
+ AnimSay(CurrentHedgehog, loc("Your deaths will be avenged, cannibals!"), SAY_SHOUT, 0)
+ cannibalsDeadFresh = false
+ end
+end
+
+function onPrecise()
+ if GameTime > 3000 and AnimInProgress() then
+ SetAnimSkip(true)
+ end
+end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Missions/Campaign/A_Classic_Fairytale/epil.lua Mon Jul 01 23:23:22 2013 +0300
@@ -0,0 +1,433 @@
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Animate.lua")
+
+-----------------------------Constants---------------------------------
+leaksNum = 1
+denseNum = 2
+waterNum = 3
+buffaloNum = 4
+chiefNum = 5
+girlNum = 6
+wiseNum = 7
+ramonNum = 8
+spikyNum = 9
+princessNum = 10
+
+denseScene = 1
+princessScene = 2
+waterScene = 3
+cyborgScene = 4
+
+nativeNames = {loc("Leaks A Lot"), loc("Dense Cloud"), loc("Fiery Water"),
+ loc("Raging Buffalo"), loc("Righteous Beard"), loc("Fell From Grace"),
+ loc("Wise Oak"), loc("Ramon"), loc("Spiky Cheese"),
+ loc("Fell From Heaven")
+ }
+nativeHats = {"Rambo", "RobinHood", "pirate_jack", "zoo_Bunny", "IndianChief",
+ "tiara", "AkuAku", "rasta", "hair_yellow", "tiara"}
+
+nativePosCyborg = {{1900, 508}, {480, 1321}, {2927, 873},
+ {1325, 905}, {3190, 1424}, {1442, 857},
+ {1134, 1278}, {2881, 853}, {2974, 897},
+ {2033, 511}}
+nativeDirCyborg = {"Right", "Right", "Left", "Right", "Right", "Left", "Right", "Right", "Left", "Left"}
+
+nativePosPrincess = {{1930, 508}, {480, 1321}, {2927, 873},
+ {1325, 905}, {3190, 1424}, {2033, 511},
+ {1134, 1278}, {2881, 853}, {2974, 897},
+ {1900, 508}}
+nativeDirPrincess = {"Right", "Right", "Left", "Right", "Right", "Left", "Right", "Right", "Left", "Right"}
+
+nativePosDense = {{1930, 508}, {2285, 772}, {2927, 873},
+ {1325, 905}, {3190, 1424}, {1442, 857},
+ {1134, 1278}, {480, 1321}, {2974, 897},
+ {2033, 511}}
+nativeDirDense = {"Right", "Left", "Left", "Right", "Right", "Left", "Right", "Right", "Left", "Left"}
+
+nativePosWater = {{1900, 508}, {2033, 511}, {2285, 772},
+ {1325, 905}, {3190, 1424}, {1442, 857},
+ {1134, 1278}, {480, 1321}, {2974, 897},
+ {1980, 511}}
+nativeDirWater = {"Right", "Left", "Left", "Right", "Right", "Left", "Right", "Right", "Left", "Left"}
+
+prisonPos = {2285, 772}
+
+brainNum = 1
+corpseNum = 2
+brutalNum = 3
+earNum = 4
+hanniNum = 5
+
+cannibalNames = {loc("Brainiac"), loc("Corpse Thrower"), loc("Brutal Lily"), loc("Ear Sniffer"), loc("Hannibal")}
+cannibalHats = {"Zombi", "AkuAku", "Zombi", "Zombi", "IndianChief"}
+cannibalPos = {{533, 1304}, {1184, 1282}, {1386, 883}, {2854, 834}, {3243, 1415}}
+cannibalDir = {"Left", "Left", "Left", "Right", "Left"}
+-----------------------------Variables---------------------------------
+natives = {}
+cannibals = {}
+traitor = nil
+crate = nil
+
+startAnim = {}
+
+gearDead = {}
+--------------------------Anim skip functions--------------------------
+function SkipStartAnim()
+ SetGearMessage(CurrentHedgehog, 0)
+ AnimSwitchHog(natives[1])
+end
+
+function AfterStartAnim()
+ crate = SpawnHealthCrate(0, 0)
+ SetGearMessage(CurrentHedgehog, 0)
+ AddNewEvent(CheckCrateTaken, {}, DoCrateTaken, {}, 1)
+ TurnTimeLeft = 0
+ ShowMission("Epilogue", "That's all folks!", "You have successfully finished the campaign!|If you wish to replay, there are other possible endings, too!|You can practice moving around and using utilities in this mission.|However, it will never end!", 1, 0)
+end
+
+---------------------------Events-------------------------------------
+function CheckCrateTaken()
+ return gearDead[crate]
+end
+
+function DoCrateTaken()
+ crate = SpawnHealthCrate(0, 0)
+end
+-----------------------------Animations--------------------------------
+function AnimationSetup()
+ if m8Scene == cyborgScene then
+ SetupAnimCyborg()
+ elseif m8Scene == princessScene then
+ SetupAnimPrincess()
+ elseif m8Scene == waterScene then
+ SetupAnimWater()
+ else
+ SetupAnimDense()
+ end
+ AddSkipFunction(startAnim, SkipStartAnim, {})
+end
+
+function SetupAnimWater()
+ startAnim = {
+ {func = AnimWait, args = {natives[1], 3000}},
+ {func = AnimCaption, args = {natives[ramonNum], "Back in the village, the two tribes finally started to live in harmony.", 5000}},
+ {func = AnimSay, args = {natives[ramonNum], "You got a killer mask there, amigo!", SAY_SAY, 5500}},
+ {func = AnimSay, args = {cannibals[brainNum], "Thanks, man! It really means a lot to me.", SAY_SAY, 6000}},
+ {func = AnimSay, args = {natives[wiseNum], "So, uhmm, how did you manage to teleport them so far?", SAY_SAY, 8000}},
+ {func = AnimSay, args = {cannibals[corpseNum], "It's all about the right carrots, you know.", SAY_SAY, 7000}},
+ {func = AnimSay, args = {natives[wiseNum], "Of course! It's all obvious now!", SAY_SAY, 4500}},
+ {func = AnimSay, args = {natives[chiefNum], "I can't believe how blind we were...", SAY_SAY, 4500}},
+ {func = AnimSay, args = {natives[chiefNum], "Fighting instead of cultivating a beautiful friendship.", SAY_SAY, 8500}},
+ {func = AnimSay, args = {cannibals[hanniNum], "One shall not judge one by one's appearance!", SAY_SAY, 7000}},
+ {func = AnimSay, args = {natives[chiefNum], "You speak great truth, Hannibal. Here, take a sip!", SAY_SAY, 7500}},
+ {func = AnimVisualGear, args = {cannibals[hanniNum], cannibalPos[hanniNum][1], cannibalPos[hanniNum][2], vgtSmoke, 0, true}},
+ {func = AnimWait, args = {natives[1], 1000}},
+ {func = AnimVisualGear, args = {cannibals[hanniNum], cannibalPos[hanniNum][1], cannibalPos[hanniNum][2], vgtSmoke, 0, true}},
+ {func = AnimWait, args = {natives[1], 1000}},
+ {func = AnimVisualGear, args = {cannibals[hanniNum], cannibalPos[hanniNum][1], cannibalPos[hanniNum][2], vgtSmoke, 0, true}},
+ {func = AnimWait, args = {natives[1], 1000}},
+ {func = AnimSay, args = {natives[leaksNum], "It's amazing how quickly our lives can change...", SAY_SAY, 7000}},
+ {func = AnimSay, args = {natives[waterNum], "Aye! Fellow! Let me exit this chamber of doom!", SAY_SAY, 7000}},
+ {func = AnimTurn, args = {natives[princessNum], "Right"}},
+ {func = AnimSay, args = {natives[princessNum], "It's your fault you're there!", SAY_SAY, 5000}},
+ {func = AnimTurn, args = {natives[princessNum], "Left"}},
+ {func = AnimSay, args = {natives[leaksNum], "I always suspected him!", SAY_SAY, 3000}},
+ {func = AnimSay, args = {natives[leaksNum], "Nobody takes walks every day!", SAY_SAY, 4000}},
+ {func = AnimSay, args = {natives[princessNum], "I don't know who I can trust anymore.", SAY_SAY, 6000}},
+ {func = AnimSay, args = {natives[princessNum], "Everywhere I look, I see hogs walking around...", SAY_SAY, 7000}},
+ {func = AnimSay, args = {natives[princessNum], "...and I think they are up to something. Something bad!", SAY_SAY, 8000}},
+ {func = AnimMove, args = {natives[leaksNum], "Right", nativePosWater[princessNum][1] - 30, nativePosWater[princessNum][2]}},
+ {func = AnimSay, args = {natives[leaksNum], "You can always trust me! I love you!", SAY_SAY, 6000}},
+ {func = AnimSay, args = {natives[princessNum], "I know and I'm terribly sorry!", SAY_SAY, 5000}},
+ {func = AnimSay, args = {natives[princessNum], "I love Dense Cloud now!", SAY_SAY, 4000}},
+ {func = AnimTurn, args = {natives[princessNum], "Right"}},
+ {func = AnimMove, args = {natives[denseNum], "Left", nativePosWater[princessNum][1] + 20, nativePosWater[princessNum][2]}},
+ {func = AnimSay, args = {natives[denseNum], "Problems, dude? Chillax!", SAY_SAY, 4000}},
+ {func = AnimTurn, args = {natives[leaksNum], "Left"}},
+ {func = AnimSay, args = {natives[leaksNum], "(T_T)", SAY_SAY, 6000}},
+ {func = AnimSwitchHog, args = {natives[leaksNum]}},
+ }
+end
+
+function SetupAnimDense()
+ startAnim = {
+ {func = AnimWait, args = {natives[1], 3000}},
+ {func = AnimCaption, args = {natives[ramonNum], "Back in the village, the two tribes finally started to live in harmony.", 5000}},
+ {func = AnimSay, args = {natives[ramonNum], "You got a killer mask there, amigo!", SAY_SAY, 5500}},
+ {func = AnimSay, args = {cannibals[brainNum], "Thanks, man! It really means a lot to me.", SAY_SAY, 6000}},
+ {func = AnimSay, args = {natives[wiseNum], "So, uhmm, how did you manage to teleport them so far?", SAY_SAY, 8000}},
+ {func = AnimSay, args = {cannibals[corpseNum], "It's all about the right carrots, you know.", SAY_SAY, 7000}},
+ {func = AnimSay, args = {natives[wiseNum], "Of course! It's all obvious now!", SAY_SAY, 4500}},
+ {func = AnimSay, args = {natives[chiefNum], "I can't believe how blind we were...", SAY_SAY, 4500}},
+ {func = AnimSay, args = {natives[chiefNum], "Fighting instead of cultivating a beautiful friendship.", SAY_SAY, 8500}},
+ {func = AnimSay, args = {cannibals[hanniNum], "One shall not judge one by one's appearance!", SAY_SAY, 7000}},
+ {func = AnimSay, args = {natives[chiefNum], "You speak great truth, Hannibal. Here, take a sip!", SAY_SAY, 7500}},
+ {func = AnimVisualGear, args = {cannibals[hanniNum], cannibalPos[hanniNum][1], cannibalPos[hanniNum][2], vgtSmoke, 0, true}},
+ {func = AnimWait, args = {natives[1], 1000}},
+ {func = AnimVisualGear, args = {cannibals[hanniNum], cannibalPos[hanniNum][1], cannibalPos[hanniNum][2], vgtSmoke, 0, true}},
+ {func = AnimWait, args = {natives[1], 1000}},
+ {func = AnimVisualGear, args = {cannibals[hanniNum], cannibalPos[hanniNum][1], cannibalPos[hanniNum][2], vgtSmoke, 0, true}},
+ {func = AnimWait, args = {natives[1], 1000}},
+ {func = AnimSay, args = {natives[waterNum], "...And then I took a stroll...", SAY_SAY, 4000}},
+ {func = AnimSay, args = {natives[leaksNum], "It's amazing how quickly our lives can change...", SAY_SAY, 7000}},
+ {func = AnimSay, args = {natives[denseNum], "Dude, let me out!", SAY_SAY, 3000}},
+ {func = AnimSay, args = {natives[denseNum], "I already said I'm sorry!", SAY_SAY, 4000}},
+ {func = AnimTurn, args = {natives[princessNum], "Right"}},
+ {func = AnimSay, args = {natives[princessNum], "Traitors don't get to shout around here!", SAY_SAY, 7000}},
+ {func = AnimTurn, args = {natives[princessNum], "Left"}},
+ {func = AnimSay, args = {natives[leaksNum], "I still can't believe he sold us out like that.", SAY_SAY, 8000}},
+ {func = AnimSay, args = {natives[princessNum], "I don't know who I can trust anymore.", SAY_SAY, 6000}},
+ {func = AnimMove, args = {natives[leaksNum], "Right", nativePosDense[princessNum][1] - 30, nativePosDense[princessNum][2]}},
+ {func = AnimSay, args = {natives[leaksNum], "You can always trust me!", SAY_SAY, 4000}},
+ {func = AnimSay, args = {natives[princessNum], "I know, my hero!", SAY_SAY, 3000}},
+ {func = AnimSay, args = {natives[princessNum], "...xoxo...", SAY_SAY, 2000}},
+ {func = AnimSwitchHog, args = {natives[leaksNum]}},
+ }
+end
+
+function SetupAnimCyborg()
+ startAnim = {
+ {func = AnimWait, args = {natives[1], 3000}},
+ {func = AnimCaption, args = {natives[denseNum], "Back in the village, the two tribes finally started to live in harmony.", 5000}},
+ {func = AnimSay, args = {natives[denseNum], "Dude, that outfit is so kool!", SAY_SAY, 4500}},
+ {func = AnimSay, args = {cannibals[brainNum], "Thanks, dude! It really means a lot to me.", SAY_SAY, 6000}},
+ {func = AnimSay, args = {natives[wiseNum], "So, uhmm, how did you manage to teleport them so far?", SAY_SAY, 8000}},
+ {func = AnimSay, args = {cannibals[corpseNum], "It's all about the right carrots, you know.", SAY_SAY, 7000}},
+ {func = AnimSay, args = {natives[wiseNum], "Of course! It's all obvious now!", SAY_SAY, 4500}},
+ {func = AnimSay, args = {natives[chiefNum], "I can't believe how blind we were...", SAY_SAY, 4500}},
+ {func = AnimSay, args = {natives[chiefNum], "Fighting instead of cultivating a beautiful friendship.", SAY_SAY, 8500}},
+ {func = AnimSay, args = {cannibals[hanniNum], "One shall not judge one by one's appearance!", SAY_SAY, 7000}},
+ {func = AnimSay, args = {natives[chiefNum], "You speak great truth, Hannibal. Here, take a sip!", SAY_SAY, 7500}},
+ {func = AnimVisualGear, args = {cannibals[hanniNum], cannibalPos[hanniNum][1], cannibalPos[hanniNum][2], vgtSmoke, 0, true}},
+ {func = AnimWait, args = {natives[1], 1000}},
+ {func = AnimVisualGear, args = {cannibals[hanniNum], cannibalPos[hanniNum][1], cannibalPos[hanniNum][2], vgtSmoke, 0, true}},
+ {func = AnimWait, args = {natives[1], 1000}},
+ {func = AnimVisualGear, args = {cannibals[hanniNum], cannibalPos[hanniNum][1], cannibalPos[hanniNum][2], vgtSmoke, 0, true}},
+ {func = AnimWait, args = {natives[1], 1000}},
+ {func = AnimSay, args = {natives[waterNum], "...And then I took a stroll...", SAY_SAY, 4000}},
+ {func = AnimSay, args = {natives[leaksNum], "I'm glad this is over!", SAY_SAY, 4000}},
+ {func = AnimMove, args = {natives[princessNum], "Right", nativePosCyborg[princessNum][1] + 30, nativePosCyborg[princessNum][2]}},
+ {func = AnimSay, args = {natives[princessNum], "I was so scared.", SAY_SAY, 2500}},
+ {func = AnimMove, args = {natives[leaksNum], "Right", nativePosCyborg[princessNum][1], nativePosCyborg[princessNum][2]}},
+ {func = AnimSay, args = {natives[leaksNum], "You have nothing to be afraid of now.", SAY_SAY, 6000}},
+ {func = AnimSay, args = {natives[leaksNum], "I'll protect you!", SAY_SAY, 3000}},
+ {func = AnimTurn, args = {natives[princessNum], "Left"}},
+ {func = AnimSay, args = {natives[princessNum], "You're so brave...I feel safe with you.", SAY_SAY, 6500}},
+ {func = AnimSay, args = {natives[princessNum], "I think I love you!", SAY_SAY, 3500}},
+ {func = AnimSay, args = {natives[leaksNum], "I...like being with you too.", SAY_SAY, 4500}},
+ }
+end
+
+function SetupAnimPrincess()
+ startAnim = {
+ {func = AnimWait, args = {natives[1], 3000}},
+ {func = AnimCaption, args = {natives[denseNum], "Back in the village, the two tribes finally started to live in harmony.", 5000}},
+ {func = AnimSay, args = {natives[denseNum], "Dude, that outfit is so kool!", SAY_SAY, 4500}},
+ {func = AnimSay, args = {cannibals[brainNum], "Thanks, dude! It really means a lot to me.", SAY_SAY, 6000}},
+ {func = AnimSay, args = {natives[wiseNum], "So, uhmm, how did you manage to teleport them so far?", SAY_SAY, 8000}},
+ {func = AnimSay, args = {cannibals[corpseNum], "It's all about the right carrots, you know.", SAY_SAY, 7000}},
+ {func = AnimSay, args = {natives[wiseNum], "Of course! It's all obvious now!", SAY_SAY, 4500}},
+ {func = AnimSay, args = {natives[chiefNum], "I can't believe how blind we were...", SAY_SAY, 4500}},
+ {func = AnimSay, args = {natives[chiefNum], "Fighting instead of cultivating a beautiful friendship.", SAY_SAY, 8500}},
+ {func = AnimSay, args = {cannibals[hanniNum], "One shall not judge one by one's appearance!", SAY_SAY, 7000}},
+ {func = AnimSay, args = {natives[chiefNum], "You speak great truth, Hannibal. Here, take a sip!", SAY_SAY, 7500}},
+ {func = AnimVisualGear, args = {cannibals[hanniNum], cannibalPos[hanniNum][1], cannibalPos[hanniNum][2], vgtSmoke, 0, true}},
+ {func = AnimWait, args = {natives[1], 1000}},
+ {func = AnimVisualGear, args = {cannibals[hanniNum], cannibalPos[hanniNum][1], cannibalPos[hanniNum][2], vgtSmoke, 0, true}},
+ {func = AnimWait, args = {natives[1], 1000}},
+ {func = AnimVisualGear, args = {cannibals[hanniNum], cannibalPos[hanniNum][1], cannibalPos[hanniNum][2], vgtSmoke, 0, true}},
+ {func = AnimWait, args = {natives[1], 1000}},
+ {func = AnimSay, args = {natives[buffaloNum], "So I shook my fist in the air!", SAY_SAY, 5000}},
+ {func = AnimSay, args = {cannibals[brutalNum], "Well that was an unnecessary act of violence.", SAY_SAY, 7000}},
+ {func = AnimSay, args = {natives[waterNum], "...And then I took a stroll...", SAY_SAY, 4000}},
+ {func = AnimSay, args = {natives[leaksNum], "I'm glad this is over!", SAY_SAY, 4000}},
+ {func = AnimSay, args = {natives[girlNum], "I still can't believe you forgave her!", SAY_SAY, 6000}},
+ {func = AnimSay, args = {natives[girlNum], "She endangered the whole tribe!", SAY_SAY, 5000}},
+ {func = AnimSay, args = {natives[leaksNum], "It wasn't her fault!", SAY_SAY, 4000}},
+ {func = AnimSay, args = {natives[leaksNum], "We oppressed her, the only woman in the tribe!", SAY_SAY, 7000}},
+ {func = AnimSay, args = {natives[girlNum], "The only woman, huh?", SAY_SAY, 4000}},
+ {func = AnimSay, args = {natives[girlNum], "Then what am I?", SAY_SAY, 4000}},
+ {func = AnimSay, args = {natives[leaksNum], "Of course, but you're...special.", SAY_SAY, 5000}},
+ {func = AnimSay, args = {natives[girlNum], "Sure!", SAY_SAY, 2000}},
+ {func = AnimTurn, args = {natives[leaksNum], "Left"}},
+ {func = AnimSay, args = {natives[leaksNum], "We're terribly sorry!", SAY_SAY, 4000}},
+ {func = AnimSay, args = {natives[princessNum], "I don't know if I can forget what you've done!", SAY_SAY, 7000}},
+ {func = AnimTurn, args = {natives[princessNum], "Left"}},
+ {func = AnimMove, args = {natives[princessNum], "Left", nativePosPrincess[princessNum][1] - 10, nativePosPrincess[princessNum][2]}},
+ {func = AnimSwitchHog, args = {natives[leaksNum]}}
+ }
+end
+-----------------------------Misc--------------------------------------
+function GetVariables()
+ m8Scene = tonumber(GetCampaignVar("M8Scene"))
+end
+
+function AddHogs()
+ AddTeam(loc("Natives"), 29439, "Bone", "Island", "HillBilly", "cm_birdy")
+ for i = 1, 5 do
+ natives[i] = AddHog(nativeNames[i], 0, 100, nativeHats[i])
+ end
+
+ AddTeam(loc("More Natives"), 29439, "Bone", "Island", "HillBilly", "cm_birdy")
+ for i = 6, 10 do
+ natives[i] = AddHog(nativeNames[i], 0, 100, nativeHats[i])
+ end
+
+ AddTeam(loc("Cannibals"), 29439, "Bone", "Island", "HillBilly", "cm_birdy")
+ for i = 1, 5 do
+ cannibals[i] = AddHog(cannibalNames[i], 0, 100, cannibalHats[i])
+ end
+
+ if m8Scene == denseScene or m8Scene == waterScene then
+ AddTeam(loc("Traitors"), 29439, "Bone", "Island", "HillBilly", "cm_birdy")
+ if m8Scene == denseScene then
+ DeleteGear(natives[2])
+ natives[2] = AddHog(nativeNames[2], 0, 100, nativeHats[2])
+ else
+ DeleteGear(natives[3])
+ natives[3] = AddHog(nativeNames[3], 0, 100, nativeHats[3])
+ end
+ end
+
+ SetGearPositions()
+end
+
+function SetGearPositions()
+ if m8Scene == cyborgScene then
+ for i = 1, 10 do
+ AnimSetGearPosition(natives[i], unpack(nativePosCyborg[i]))
+ AnimTurn(natives[i], nativeDirCyborg[i])
+ end
+ elseif m8Scene == waterScene then
+ for i = 1, 10 do
+ AnimSetGearPosition(natives[i], unpack(nativePosWater[i]))
+ AnimTurn(natives[i], nativeDirWater[i])
+ end
+ elseif m8Scene == denseScene then
+ for i = 1, 10 do
+ AnimSetGearPosition(natives[i], unpack(nativePosDense[i]))
+ AnimTurn(natives[i], nativeDirDense[i])
+ end
+ else
+ for i = 1, 10 do
+ AnimSetGearPosition(natives[i], unpack(nativePosPrincess[i]))
+ AnimTurn(natives[i], nativeDirPrincess[i])
+ end
+ end
+
+ for i = 1, 5 do
+ AnimSetGearPosition(cannibals[i], unpack(cannibalPos[i]))
+ AnimTurn(cannibals[i], cannibalDir[i])
+ end
+end
+
+function SetupPlace()
+ if m8Scene == denseScene or m8Scene == waterScene then
+ PlaceGirder(2296, 798, 4)
+ PlaceGirder(2296, 700, 4)
+ PlaceGirder(2225, 750, 2)
+ PlaceGirder(2245, 750, 2)
+ PlaceGirder(2265, 750, 2)
+ PlaceGirder(2305, 750, 2)
+ PlaceGirder(2345, 750, 2)
+ PlaceGirder(2365, 750, 2)
+ end
+ if m8Scene == denseScene then
+ traitor = natives[denseNum]
+ elseif m8Scene == waterScene then
+ traitor = natives[waterNum]
+ end
+end
+-----------------------------Main Functions----------------------------
+function onGameInit()
+ Seed = 1
+ GameFlags = gfOneClanMode
+ TurnTime = 60000
+ CaseFreq = 0
+ MinesNum = 0
+ MinesTime = 3000
+ Explosives = 0
+ Delay = 10
+ Map = "Hogville"
+ Theme = "Nature"
+ SuddenDeathTurns = 3000
+
+ GetVariables()
+ AddHogs()
+ AnimInit()
+end
+
+function onGameStart()
+ SetupPlace()
+ AnimationSetup()
+ AddAnim(startAnim)
+ AddFunction({func = AfterStartAnim, args = {}})
+end
+
+function onGameTick()
+ AnimUnWait()
+ if ShowAnimation() == false then
+ return
+ end
+ ExecuteAfterAnimations()
+ CheckEvents()
+end
+
+function onGearDelete(gear)
+ gearDead[gear] = true
+end
+
+function onAmmoStoreInit()
+ SetAmmo(amAirStrike, 9, 0, 0, 0)
+ SetAmmo(amBaseballBat, 9, 0, 0, 0)
+ SetAmmo(amBazooka, 9, 0, 0, 0)
+ SetAmmo(amBlowTorch, 9, 0, 0, 0)
+ SetAmmo(amClusterBomb,9, 0, 0, 0)
+ SetAmmo(amDEagle, 9, 0, 0, 0)
+ SetAmmo(amDrill, 9, 0, 0, 4)
+ SetAmmo(amDynamite, 9, 0, 0, 3)
+ SetAmmo(amFirePunch, 9, 0, 0, 0)
+ SetAmmo(amFlamethrower, 9, 0, 0, 3)
+ SetAmmo(amGirder, 9, 0, 0, 0)
+ SetAmmo(amGrenade, 9, 0, 0, 0)
+ SetAmmo(amHammer, 9, 0, 0, 0)
+ SetAmmo(amJetpack, 9, 0, 0, 0)
+ SetAmmo(amLandGun, 9, 0, 0, 0)
+ SetAmmo(amLowGravity, 9, 0, 0, 2)
+ SetAmmo(amMine, 9, 0, 0, 2)
+ SetAmmo(amMolotov, 9, 0, 0, 3)
+ SetAmmo(amMortar, 9, 0, 0, 4)
+ SetAmmo(amNapalm, 9, 0, 0, 4)
+ SetAmmo(amParachute, 9, 0, 0, 0)
+ SetAmmo(amPickHammer, 9, 0, 0, 0)
+ SetAmmo(amPortalGun, 9, 0, 0, 0)
+ SetAmmo(amRope, 9, 0, 0, 0)
+ SetAmmo(amRCPlane, 9, 0, 0, 0)
+ SetAmmo(amSkip, 9, 0, 0, 0)
+ SetAmmo(amShotgun, 9, 0, 0, 0)
+ SetAmmo(amSMine, 9, 0, 0, 2)
+ SetAmmo(amSniperRifle, 9, 0, 0, 0)
+ SetAmmo(amSnowball, 9, 0, 0, 0)
+ SetAmmo(amSwitch, 9, 0, 0, 0)
+ SetAmmo(amTeleport, 9, 0, 0, 0)
+ SetAmmo(amWatermelon, 9, 0, 0, 0)
+ SetAmmo(amWhip, 9, 0, 0, 0)
+end
+
+function onNewTurn()
+ if AnimInProgress() then
+ TurnTimeLeft = -1
+ return
+ end
+ if CurrentHedgehog == traitor then
+ TurnTimeLeft = 0
+ else
+ TurnTimeLeft = -1
+ end
+end
+
+function onPrecise()
+ if GameTime > 2500 then
+ SetAnimSkip(true)
+ end
+end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Missions/Campaign/A_Classic_Fairytale/family.lua Mon Jul 01 23:23:22 2013 +0300
@@ -0,0 +1,569 @@
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Animate.lua")
+
+-----------------------------Map--------------------------------------
+local map =
+{
+ "\255\242\4\218\132\0\53\4\253\0\0\53\4\253\132\0\102\5\92\0\0\102\5\92\132\0\106\5\205\0\0\106\5\205\132\1\1\6\37\0",
+ "\1\1\6\37\132\1\124\6\160\0\1\113\6\160\132\2\157\6\111\0\2\164\6\107\132\2\252\6\178\0\2\252\6\178\132\3\224\4\179\0",
+ "\3\224\4\179\132\3\38\2\209\0\3\38\2\209\132\4\109\3\179\0\4\109\3\179\132\5\124\3\172\0\5\128\3\172\132\6\69\4\239\0",
+ "\6\69\4\239\132\7\175\4\32\0\7\172\4\46\132\8\116\5\18\0\3\38\2\213\132\3\41\1\244\0\3\41\1\244\132\3\94\2\245\0",
+ "\8\127\5\8\132\8\127\0\14\0\8\127\0\14\132\8\194\5\29\0\8\194\5\29\132\9\36\5\82\0\9\29\5\75\132\9\180\5\103\0",
+ "\9\194\5\92\132\10\51\6\5\0\10\51\6\5\132\10\216\5\152\0\10\227\5\145\132\11\189\5\212\0\11\189\5\212\132\12\91\5\131\0",
+ "\12\91\5\131\132\12\253\5\191\0\12\253\5\191\132\13\149\5\106\0\13\149\5\106\132\16\11\5\106\0\14\19\5\110\132\14\16\4\236\0",
+ "\14\16\4\236\132\15\66\4\236\0\15\66\4\236\132\15\66\5\110\0\14\79\4\194\132\15\6\4\194\0\14\255\4\176\132\14\255\4\49\0",
+ "\14\255\4\49\132\14\76\4\53\0\14\76\4\53\132\14\76\4\201\0\14\125\4\74\128\14\128\4\187\0\14\188\4\77\128\14\185\4\179\0",
+ "\14\111\4\39\129\14\76\3\252\0\14\72\3\249\129\14\72\3\147\0\14\72\3\147\129\14\97\3\235\0\14\97\3\235\129\14\146\4\28\0",
+ "\14\202\4\28\129\14\248\3\238\0\14\248\3\238\129\15\17\3\133\0\15\17\3\133\129\15\27\3\235\0\15\27\3\235\129\14\230\4\49\0",
+ "\1\124\6\220\130\1\244\7\13\0\1\244\7\13\130\2\104\6\206\0\2\100\6\206\130\2\30\6\178\0\2\12\6\181\130\1\135\6\213\0",
+ "\3\172\7\136\130\15\41\7\136\0\15\41\7\136\130\15\41\7\62\0\15\41\7\62\130\3\175\7\52\0\3\175\7\52\130\3\126\6\206\0",
+ "\3\126\6\206\130\3\122\7\133\0\3\122\7\133\130\3\186\7\136\0\8\123\7\94\136\9\173\7\101\0\8\88\7\66\130\8\88\7\119\0",
+ "\9\212\7\69\130\9\212\7\126\0\8\155\0\14\133\8\151\5\11\0\8\190\2\160\131\8\194\5\1\0\14\83\3\235\131\14\114\4\21\0",
+ "\15\10\3\196\131\15\10\3\235\0\15\10\3\235\131\14\220\4\32\0\14\65\5\47\137\15\20\5\36\0\15\41\5\82\132\15\41\5\82\0",
+ "\3\94\3\17\138\4\137\5\124\0\3\221\3\119\138\5\57\4\250\0\4\102\4\67\160\5\26\4\74\0\4\113\5\36\161\5\142\4\222\0",
+ "\4\42\5\216\169\9\89\6\26\0\6\100\5\22\145\8\134\5\64\0\6\255\4\197\140\7\161\4\120\0\7\214\4\204\146\7\214\4\204\0",
+ "\10\55\6\97\147\11\13\5\247\0\11\59\6\26\146\11\224\6\30\0\12\95\6\16\153\14\55\6\90\0\13\173\5\226\153\15\196\5\212\0",
+ "\15\172\7\91\152\15\165\5\230\0\15\235\7\221\142\255\238\7\207\0\14\248\6\188\152\3\217\6\178\0\3\112\6\83\143\3\31\7\101\0",
+ "\3\73\7\143\140\3\73\7\143\0\15\62\7\13\140\15\62\7\13\0\15\101\7\157\140\15\101\7\157\0\2\181\6\220\141\1\205\7\108\0",
+ "\2\86\6\160\137\2\150\6\128\0\2\26\6\153\134\1\96\6\195\0\1\82\6\241\136\1\226\7\59\0\2\157\7\98\155\2\157\7\98\0",
+ "\1\64\7\80\149\255\249\7\27\0\1\4\6\174\148\0\25\6\86\0\0\211\6\58\139\0\7\5\219\0\0\35\5\159\142\0\4\5\47\0",
+ "\8\123\0\14\199\8\187\0\11\0\16\14\5\99\199\16\14\7\245\0\255\235\4\218\199\255\238\8\25\0\8\67\2\72\202\8\208\2\72\0",
+ "\8\141\1\251\202\8\141\0\74\0\8\201\2\143\195\8\204\4\49\0\8\84\2\185\205\8\204\2\188\0\8\99\2\230\205\8\187\2\230\0",
+ "\8\165\3\41\131\8\144\3\3\0\8\144\3\3\131\8\60\2\248\0\8\60\2\248\131\7\252\3\59\0\7\252\3\59\131\8\137\3\31\0",
+ "\8\56\3\20\131\8\102\3\20\0\8\60\3\13\194\8\60\3\13\0\8\60\3\3\128\8\60\3\31\0\7\238\3\66\128\7\214\3\84\0",
+ "\7\217\3\87\128\7\217\3\98\0\7\217\3\87\128\7\200\3\91\0\6\209\4\70\208\8\18\4\95\0\0\11\4\225\131\0\0\8\21\0",
+ "\15\224\5\99\131\15\245\7\252\0\15\242\5\191\192\15\196\6\33\0\15\196\6\33\192\15\245\6\209\0\15\245\6\209\192\15\193\7\115\0",
+ "\15\193\7\115\192\15\235\8\18\0\15\249\5\223\196\15\217\6\40\0\15\217\6\40\196\16\4\6\188\0\15\245\6\16\196\16\21\7\77\0",
+ "\16\0\6\245\196\15\214\7\112\0\15\207\7\129\196\16\0\8\4\0\15\245\7\80\196\16\4\7\207\0\15\221\5\85\196\16\11\5\184\0",
+}
+--------------------------------------------Constants------------------------------------
+choiceAccepted = 1
+choiceRefused = 2
+choiceAttacked = 3
+
+choiceEliminate = 1
+choiceSpare = 2
+
+leaksNum = 1
+denseNum = 2
+waterNum = 3
+buffaloNum = 4
+chiefNum = 5
+girlNum = 6
+wiseNum = 7
+
+nativeNames = {loc("Leaks A Lot"), loc("Dense Cloud"), loc("Fiery Water"),
+ loc("Raging Buffalo"), loc("Righteous Beard"), loc("Fell From Grace"),
+ loc("Wise Oak"), loc("Ramon"), loc("Spiky Cheese")
+ }
+
+nativeUnNames = {loc("Zork"), loc("Steve"), loc("Jack"),
+ loc("Lee"), loc("Elmo"), loc("Rachel"),
+ loc("Muriel")}
+
+nativeHats = {"Rambo", "RobinHood", "pirate_jack", "zoo_Bunny", "IndianChief",
+ "tiara", "AkuAku", "rasta", "hair_yellow"}
+
+nativePos = {{110, 1310}, {984, 1907}, {1040, 1907}}
+nativePos2 = {196, 1499}
+
+cyborgNames = {loc("Unit 0x0007"), loc("Hogminator"), loc("Carol"),
+ loc("Blender"), loc("Elderbot"), loc("Fiery Water")}
+cyborgsDif = {2, 2, 2, 2, 2, 1}
+cyborgsHealth = {45, 45, 45, 40, 40, 20}
+cyborgPos = {945, 1216}
+cyborgsNum = 6
+cyborgsPos = {{2243, 1043}, {3588, 1227}, {2781, 1388},
+ {3749, 1040}, {2475, 1338}, {3853, 881}}
+cyborgsDir = {"Left", "Left", "Left", "Left", "Left", "Right"}
+
+princessPos = {3737, 1181}
+crateConsts = {}
+reactions = {}
+
+nativeMidPos = {1991, 841}
+cyborgMidPos = {2109, 726}
+nativeMidPos2 = {2250, 1071}
+-----------------------------Variables---------------------------------
+natives = {}
+native = nil
+
+cyborgs = {}
+cyborg = nil
+
+gearDead = {}
+hedgeHidden = {}
+
+startAnim = {}
+midAnim = {}
+
+freshDead = nil
+crates = {}
+cratesNum = 0
+-----------------------------Animations--------------------------------
+function EmitDenseClouds(dir)
+ local dif
+ if dir == "Left" then
+ dif = 10
+ else
+ dif = -10
+ end
+ AnimInsertStepNext({func = AnimVisualGear, args = {natives[1], GetX(natives[1]) + dif, GetY(natives[1]) + dif, vgtSteam, 0, true}, swh = false})
+ AnimInsertStepNext({func = AnimVisualGear, args = {natives[1], GetX(natives[1]) + dif, GetY(natives[1]) + dif, vgtSteam, 0, true}, swh = false})
+ AnimInsertStepNext({func = AnimVisualGear, args = {natives[1], GetX(natives[1]) + dif, GetY(natives[1]) + dif, vgtSteam, 0, true}, swh = false})
+ AnimInsertStepNext({func = AnimWait, args = {natives[1], 800}})
+ AnimInsertStepNext({func = AnimVisualGear, args = {natives[1], GetX(natives[1]) + dif, GetY(natives[1]) + dif, vgtSteam, 0, true}, swh = false})
+ AnimInsertStepNext({func = AnimVisualGear, args = {natives[1], GetX(natives[1]) + dif, GetY(natives[1]) + dif, vgtSteam, 0, true}, swh = false})
+ AnimInsertStepNext({func = AnimWait, args = {natives[1], 800}})
+ AnimInsertStepNext({func = AnimVisualGear, args = {natives[1], GetX(natives[1]) + dif, GetY(natives[1]) + dif, vgtSteam, 0, true}, swh = false})
+end
+
+function AnimationSetup()
+ table.insert(startAnim, {func = AnimWait, args = {natives[1], 4000}})
+ table.insert(startAnim, {func = AnimMove, args = {natives[1], "Right", unpack(nativePos2)}})
+ if m5DeployedNum == leaksNum then
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], loc("Those aliens are destroying the island!"), SAY_THINK, 5000}})
+ elseif m5DeployedNum == denseNum then
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], loc("Dude, all the plants are gone!"), SAY_THINK, 3500}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], loc("What am I gonna...eat, yo?"), SAY_THINK, 3500}})
+ elseif m5DeployedNum == girlNum then
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], loc("Fell From Heaven is the best! Fell From Heaven is the greatest!"), SAY_THINK, 7000}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], loc("Yuck! I bet they'll keep worshipping her even after I save the village!"), SAY_THINK, 7500}})
+ elseif m5DeployedNum == chiefNum then
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], loc("I'm getting old for this!"), SAY_THINK, 4000}})
+ elseif m5DeployedNum == waterNum then
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], loc("I'm getting thirsty..."), SAY_THINK, 3000}})
+ elseif m5DeployedNum == buffaloNum then
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], loc("I wonder why I'm so angry all the time..."), SAY_THINK, 6000}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], loc("It must be a childhood trauma..."), SAY_THINK, 4000}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], loc("Just wait till I get my hands on that trauma! ARGH!"), SAY_THINK, 6500}})
+ elseif m5DeployedNum == wiseNum then
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], loc("I could just teleport myself there..."), SAY_THINK, 4500}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], loc("It's a shame, I forgot how to do that!"), SAY_THINK, 4500}})
+ end
+ table.insert(startAnim, {func = AnimCustomFunction, args = {natives[1], RestoreHedge, {cyborg}}})
+ table.insert(startAnim, {func = AnimOutOfNowhere, args = {cyborg, unpack(cyborgPos)}})
+ table.insert(startAnim, {func = AnimTurn, args = {cyborg, "Left"}})
+ table.insert(startAnim, {func = AnimTurn, args = {natives[2], "Left"}})
+ table.insert(startAnim, {func = AnimTurn, args = {natives[3], "Left"}})
+ table.insert(startAnim, {func = AnimSay, args = {cyborg, loc("Hello again, ") .. nativeUnNames[m5DeployedNum] .. "!", SAY_SAY, 2500}})
+ table.insert(startAnim, {func = AnimSay, args = {cyborg, loc("I just found out that they have captured your princess!"), SAY_SAY, 7000}})
+ if m5DeployedNum == girlNum then
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], loc("Of course I have to save her. What did I expect?!"), SAY_SAY, 7000}})
+ elseif m5DeployedNum == denseNum then
+ table.insert(startAnim, {func = AnimCustomFunction, args = {natives[1], EmitDenseClouds, {"Right"}}})
+ end
+ table.insert(startAnim, {func = AnimSay, args = {cyborg, loc("She's behind that tall thingy."), SAY_SAY, 5000}})
+ table.insert(startAnim, {func = FollowGear, swh = false, args = {princess}})
+ table.insert(startAnim, {func = AnimWait, swh = false, args = {princess, 1000}})
+ table.insert(startAnim, {func = FollowGear, swh = false, args = {cyborg}})
+ table.insert(startAnim, {func = AnimSay, args = {cyborg, loc("I'm here to help you rescue her."), SAY_SAY, 5000}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[2], loc("Yo, dude, we're here, too!"), SAY_SHOUT, 4000}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[3], loc("We were trying to save her and we got lost."), SAY_SHOUT, 6000}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], loc("That's typical of you!"), SAY_SAY, 3000}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], loc("Why are you helping us, uhm...?"), SAY_SAY, 3000}})
+ table.insert(startAnim, {func = AnimSay, args = {cyborg, loc("Call me Beep! Well, 'cause I'm such a nice...person!"), SAY_SAY, 2500}})
+ table.insert(startAnim, {func = AnimDisappear, args = {cyborg, unpack(cyborgPos)}})
+ table.insert(startAnim, {func = AnimSwitchHog, args = {natives[1]}})
+ table.insert(startAnim, {func = AnimWait, args = {natives[1], 1}})
+ AddSkipFunction(startAnim, SkipStartAnim, {})
+
+ table.insert(midAnim, {func = AnimCustomFunction, args = {natives[1], RestoreHedge, {cyborg}}})
+ table.insert(midAnim, {func = AnimOutOfNowhere, args = {cyborg, unpack(cyborgMidPos)}})
+ table.insert(midAnim, {func = AnimTurn, args = {cyborg, "Left"}})
+ table.insert(midAnim, {func = AnimTeleportGear, args = {natives[1], unpack(nativeMidPos)}})
+ table.insert(midAnim, {func = AnimSay, args = {cyborg, loc("Here, let me help you save her!"), SAY_SAY, 5000}})
+ table.insert(midAnim, {func = AnimSay, args = {natives[1], loc("Thanks!"), SAY_SAY, 2000}})
+ table.insert(midAnim, {func = AnimTeleportGear, args = {natives[1], unpack(nativeMidPos2)}})
+ table.insert(midAnim, {func = AnimSay, args = {natives[1], loc("Why can't he just let her go?!"), SAY_THINK, 5000}})
+ AddSkipFunction(midAnim, SkipMidAnim, {})
+end
+
+--------------------------Anim skip functions--------------------------
+function AfterMidAnim()
+ HideHedge(cyborg)
+ SetupPlace3()
+ SetGearMessage(natives[1], 0)
+ AddNewEvent(CheckPrincessFreed, {}, DoPrincessFreed, {}, 0)
+ TurnTimeLeft = 0
+ ShowMission(loc("Family Reunion"), loc("Salvation"), loc("Get your teammates out of their natural prison and save the princess!|Hint: Drilling holes should solve everything.|Hint: It might be a good idea to place a girder before starting to drill. Just saying.|Hint: All your hedgehogs need to be above the marked height!|Hint: Leaks A Lot needs to get really close to the princess!"), 1, 7000)
+ vCirc = AddVisualGear(0,0,vgtCircle,0,true)
+ SetVisualGearValues(vCirc, 2625, 1500, 100, 255, 1, 10, 0, 120, 3, 0xff00ffff)
+end
+
+function SkipMidAnim()
+ AnimTeleportGear(natives[1], unpack(nativeMidPos2))
+ SkipStartAnim()
+end
+
+function SetupPlace3()
+ SpawnUtilityCrate(2086, 1887, amRope, 1)
+ SpawnUtilityCrate(2147, 728, amBlowTorch, 2)
+ SpawnUtilityCrate(2778, 1372, amPickHammer, 3)
+ SpawnUtilityCrate(2579, 1886, amPickHammer, 3)
+ SpawnUtilityCrate(2622, 1893, amGirder, 1)
+ SpawnUtilityCrate(2671, 1883, amPortalGun, 3)
+ SpawnUtilityCrate(2831, 1384, amGirder, 3)
+
+ SetTimer(AddGear(2725, 1387, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2760, 1351, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2805, 1287, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2831, 1376, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2684, 1409, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2637, 1428, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2278, 1280, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2311, 1160, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2339, 1162, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2362, 1184, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2407, 1117, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2437, 1143, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2472, 1309, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2495, 1331, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2536, 1340, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2569, 1360, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2619, 1379, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2596, 1246, gtMine, 0, 0, 0, 0), 5000)
+end
+
+function SkipStartAnim()
+ AnimSwitchHog(natives[1])
+ AnimWait(natives[1], 1)
+end
+
+function AfterStartAnim()
+ HideHedge(cyborg)
+ SetupPlace2()
+ SetGearMessage(natives[1], 0)
+ AddNewEvent(CheckGearDead, {natives[1]}, EndMission, {}, 0)
+ AddNewEvent(CheckGearDead, {natives[2]}, EndMission, {}, 0)
+ AddNewEvent(CheckGearDead, {natives[3]}, EndMission, {}, 0)
+ AddNewEvent(CheckGearDead, {princess}, EndMission, {}, 0)
+ AddNewEvent(CheckCyborgsDead, {}, DoCyborgsDead, {}, 0)
+ for i = 1, cyborgsNum do
+ AddNewEvent(CheckGearDead, {cyborgs[i]}, DoCyborgDead, {i}, 0)
+ end
+ AddNewEvent(CheckOutOfCluster, {}, DoOutOfCluster, {}, 1)
+ AddNewEvent(CheckOutOfGrenade, {}, DoOutOfGrenade, {}, 1)
+-- AddNewEvent(CheckNeedToHide, {}, DoNeedToHide, {}, 1)
+ TurnTimeLeft = TurnTime
+ ShowMission(loc("Family Reunion"), loc("Hostage Situation"), loc("Save the princess! All your hogs must survive!|Hint: Kill the cyborgs first! Use the ammo very carefully!|Hint: You might want to spare a girder for cover!"), 1, 7000)
+end
+
+function SetupPlace2()
+ PlaceGirder(709, 564, 7)
+ PlaceGirder(591, 677, 7)
+ PlaceGirder(473, 794, 7)
+ PlaceGirder(433, 933, 5)
+ PlaceGirder(553, 1052, 5)
+ PlaceGirder(674, 1170, 5)
+ PlaceGirder(710, 1310, 7)
+ PlaceGirder(648, 1427, 5)
+ PlaceGirder(2110, 980, 0)
+
+ SpawnAmmoCrate(814, 407, amBazooka, 4)
+ clusterCrate = SpawnAmmoCrate(862, 494, amClusterBomb, 4)
+ SpawnAmmoCrate(855, 486, amBee, 3)
+ grenadeCrate1 = SpawnAmmoCrate(849, 459, amGrenade, 4)
+ SpawnAmmoCrate(2077, 847, amWatermelon, 3)
+ grenadeCrate2 = SpawnAmmoCrate(2122, 847, amGrenade, 3)
+
+ SpawnUtilityCrate(747, 1577, amPickHammer, 1)
+ SpawnUtilityCrate(496, 1757, amGirder, 2)
+ SpawnUtilityCrate(1809, 1880, amGirder, 1)
+ SpawnUtilityCrate(530, 1747, amPortalGun, 1)
+end
+
+-----------------------------Events------------------------------------
+function CheckPrincessFreed()
+ if GetX(natives[1]) == nil or GetX(natives[2]) == nil or GetX(natives[3]) == nil or GetX(princess) == nil then
+ return false
+ end
+ return math.abs(GetX(natives[1]) - GetX(princess)) <= 15 and math.abs(GetY(natives[1]) - GetY(princess)) <= 15 and StoppedGear(natives[1])
+ and GetY(natives[2]) < 1500 and GetY(natives[3]) < 1500 and StoppedGear(natives[2]) and StoppedGear(natives[3])
+end
+
+function DoPrincessFreed()
+ AnimSay(princess, loc("Thank you, my hero!"), SAY_SAY, 0)
+ if progress and progress<7 then
+ SaveCampaignVar("Progress", "7")
+ end
+ ParseCommand("teamgone " .. loc("011101001"))
+ TurnTimeLeft = 0
+end
+
+function CheckCyborgsDead()
+ return cyborgsLeft == 0
+end
+
+function DoCyborgsDead()
+ SetGearMessage(CurrentHedgehog, 0)
+ RestoreHedge(princess)
+-- RemoveEventFunc(CheckNeedToHide)
+ AddAnim(midAnim)
+ AddFunction({func = AfterMidAnim, args = {}})
+end
+
+function DoCyborgDead(index)
+ if cyborgsLeft == 0 then
+ return
+ end
+ if index == 1 then
+ SpawnAmmoCrate(1700, 407, amBazooka, 3)
+ elseif index == 2 then
+ SpawnAmmoCrate(1862, 494, amClusterBomb, 3)
+ elseif index == 3 then
+ SpawnAmmoCrate(1855, 486, amBee, 1)
+ elseif index == 4 then
+ SpawnAmmoCrate(1849, 459, amGrenade, 3)
+ elseif index == 5 then
+ SpawnAmmoCrate(2122, 847, amGrenade, 3)
+ elseif index == 6 then
+ SpawnAmmoCrate(2077, 847, amWatermelon, 1)
+ end
+end
+
+function CheckGearsDead(gearList)
+ for i = 1, # gearList do
+ if gearDead[gearList[i]] ~= true then
+ return false
+ end
+ end
+ return true
+end
+
+
+function CheckGearDead(gear)
+ return gearDead[gear]
+end
+
+function EndMission()
+ RemoveEventFunc(CheckPrincessFreed)
+ AddCaption("So the princess was never heard of again...")
+ ParseCommand("teamgone " .. loc("Natives"))
+ ParseCommand("teamgone " .. loc("011101001"))
+ TurnTimeLeft = 0
+end
+
+function CheckOutOfCluster()
+ return CheckGearDead(clusterCrate) and GetAmmoCount(natives[1], amClusterBomb) == 0
+end
+
+function CheckOutOfGrenade()
+ return CheckGearDead(grenadeCrate1) and CheckGearDead(grenadeCrate2) and GetAmmoCount(natives[1], amGrenade) == 0
+end
+
+function DoOutOfCluster()
+ if (GetX(natives[1]) == nil) then
+ return
+ end
+ clusterCrate = SpawnAmmoCrate(GetX(natives[1]) - 50, GetY(natives[1]) - 50, amClusterBomb, 3)
+end
+
+function DoOutOfGrenade()
+ if (GetX(natives[1]) == nil) then
+ return
+ end
+ grenadeCrate2 = SpawnAmmoCrate(GetX(natives[1]) - 50, GetY(natives[1]) - 50, amGrenade, 3)
+end
+
+function CheckNeedToHide()
+ if gearDead[princess] == true then
+ return false
+ end
+ return TurnTimeLeft == 0
+end
+
+function DoNeedToHide()
+ HideHedge(princess)
+end
+-----------------------------Misc--------------------------------------
+function HideHedge(hedge)
+ if hedgeHidden[hedge] ~= true then
+ HideHog(hedge)
+ hedgeHidden[hedge] = true
+ end
+end
+
+function RestoreHedge(hedge)
+ if hedgeHidden[hedge] == true then
+ RestoreHog(hedge)
+ hedgeHidden[hedge] = false
+ end
+end
+
+function GetVariables()
+ progress = tonumber(GetCampaignVar("Progress"))
+ m5DeployedNum = tonumber(GetCampaignVar("M5DeployedNum"))
+ m2Choice = tonumber(GetCampaignVar("M2Choice"))
+ m5Choice = tonumber(GetCampaignVar("M5Choice"))
+end
+
+function SetupPlace()
+ SetHogHat(natives[1], nativeHats[m5DeployedNum])
+ SetHogName(natives[1], nativeNames[m5DeployedNum])
+ if m2Choice ~= choiceAccepted or m5Choice ~= choiceEliminate then
+ DeleteGear(cyborgs[cyborgsNum])
+ cyborgsNum = cyborgsNum - 1
+ end
+ HideHedge(cyborg)
+end
+
+function SetupAmmo()
+ AddAmmo(cyborgs[1], amBazooka, 100)
+ AddAmmo(cyborgs[1], amGrenade, 100)
+ AddAmmo(cyborgs[1], amClusterBomb, 100)
+ AddAmmo(cyborgs[1], amSniperRifle, 1)
+ AddAmmo(cyborgs[1], amDynamite, 100)
+ AddAmmo(cyborgs[1], amBaseballBat, 100)
+ AddAmmo(cyborgs[1], amMolotov, 100)
+ AddAmmo(cyborgs[1], amWatermelon, 1)
+ AddAmmo(cyborgs[1], amAirStrike, 2)
+ AddAmmo(cyborgs[1], amDrillStrike, 1)
+end
+
+function AddHogs()
+ AddTeam(loc("Natives"), 29439, "Bone", "Island", "HillBilly", "cm_birdy")
+ for i = 7, 9 do
+ natives[i-6] = AddHog(nativeNames[i], 0, 100, nativeHats[i])
+ gearDead[natives[i-6]] = false
+ end
+
+ AddTeam(loc("011101001"), 14483456, "ring", "UFO", "Robot", "cm_star")
+ cyborg = AddHog(loc("Unit 334a$7%;.*"), 0, 200, "cyborg1")
+ princess = AddHog(loc("Fell From Heaven"), 0, 333, "tiara")
+ gearDead[cyborg] = false
+ gearDead[princess] = false
+
+ AddTeam(loc("Biomechanic Team"), 14483456, "ring", "UFO", "Robot", "cm_star")
+ for i = 1, cyborgsNum do
+ cyborgs[i] = AddHog(cyborgNames[i], cyborgsDif[i], cyborgsHealth[i], "cyborg2")
+ gearDead[cyborgs[i]] = false
+ end
+ cyborgsLeft = cyborgsNum
+
+ for i = 1, 3 do
+ AnimSetGearPosition(natives[i], unpack(nativePos[i]))
+ end
+
+ AnimSetGearPosition(cyborg, unpack(cyborgPos))
+ AnimSetGearPosition(princess, unpack(princessPos))
+ AnimTurn(princess, "Left")
+
+ for i = 1, cyborgsNum do
+ AnimSetGearPosition(cyborgs[i], unpack(cyborgsPos[i]))
+ AnimTurn(cyborgs[i], cyborgsDir[i])
+ end
+end
+
+function CondNeedToTurn(hog1, hog2)
+ xl, xd = GetX(hog1), GetX(hog2)
+ if xl == nil or xd == nil then
+ return
+ end
+ if xl > xd then
+ AnimInsertStepNext({func = AnimTurn, args = {hog1, "Left"}})
+ AnimInsertStepNext({func = AnimTurn, args = {hog2, "Right"}})
+ elseif xl < xd then
+ AnimInsertStepNext({func = AnimTurn, args = {hog2, "Left"}})
+ AnimInsertStepNext({func = AnimTurn, args = {hog1, "Right"}})
+ end
+end
+
+-----------------------------Main Functions----------------------------
+
+function onGameInit()
+ Seed = 0
+ GameFlags = gfSolidLand + gfDisableLandObjects + gfDisableGirders
+ TurnTime = 60000
+ CaseFreq = 0
+ MinesNum = 0
+ MinesTime = 3000
+ Explosives = 0
+ Delay = 10
+ MapGen = 2
+ Theme = "Hell"
+ SuddenDeathTurns = 35
+
+ for i = 1, #map do
+ ParseCommand('draw ' .. map[i])
+ end
+
+ AddHogs()
+ AnimInit()
+end
+
+function onGameStart()
+ GetVariables()
+ SetupAmmo()
+ SetupPlace()
+ AnimationSetup()
+ AddAnim(startAnim)
+ AddFunction({func = AfterStartAnim, args = {}})
+end
+
+function onGameTick()
+ AnimUnWait()
+ if ShowAnimation() == false then
+ return
+ end
+ ExecuteAfterAnimations()
+ CheckEvents()
+end
+
+function onGearDelete(gear)
+ gearDead[gear] = true
+ if GetGearType(gear) == gtHedgehog then
+ if GetHogTeamName(gear) == loc("Biomechanic Team") then
+ cyborgsLeft = cyborgsLeft - 1
+ end
+ end
+end
+
+function onAmmoStoreInit()
+ SetAmmo(amSkip, 9, 0, 0, 0)
+ SetAmmo(amSwitch, 9, 0, 0, 0)
+ SetAmmo(amBazooka, 0, 0, 0, 8)
+ SetAmmo(amClusterBomb,0, 0, 0, 8)
+ SetAmmo(amBee, 0, 0, 0, 3)
+ SetAmmo(amGrenade, 0, 0, 0, 8)
+ SetAmmo(amWatermelon, 0, 0, 0, 2)
+ SetAmmo(amSniperRifle, 0, 0, 0, 3)
+ SetAmmo(amPickHammer, 0, 0, 0, 1)
+ SetAmmo(amGirder, 0, 0, 0, 3)
+ SetAmmo(amPortalGun, 0, 0, 0, 1)
+end
+
+function onNewTurn()
+ if AnimInProgress() then
+ TurnTimeLeft = -1
+ return
+ end
+ if GetHogTeamName(CurrentHedgehog) == loc("011101001") then
+ if CheckCyborgsDead() ~= true then
+ for i = 1, 3 do
+ if gearDead[natives[i]] ~= true then
+ HideHedge(natives[i])
+ end
+ end
+ end
+ TurnTimeLeft = 0
+ else
+ for i = 1, 3 do
+ if gearDead[natives[i]] ~= true then
+ RestoreHedge(natives[i])
+ end
+ end
+ end
+end
+
+function onPrecise()
+ if GameTime > 2500 and AnimInProgress() then
+ SetAnimSkip(true)
+ return
+ end
+-- HideHedge(princess)
+-- for i = 1, 5 do
+-- DeleteGear(cyborgs[i])
+-- end
+-- AddAmmo(natives[1], amTeleport, 100)
+end
Binary file share/hedgewars/Data/Missions/Campaign/A_Classic_Fairytale/first_blood.hwp has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Missions/Campaign/A_Classic_Fairytale/first_blood.lua Mon Jul 01 23:23:22 2013 +0300
@@ -0,0 +1,750 @@
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Animate.lua")
+
+-----------------------------Variables---------------------------------
+startDialogue = {}
+damageAnim = {}
+onShroomAnim = {}
+onFlowerAnim = {}
+tookParaAnim = {}
+tookPunchAnim = {}
+onMoleHeadAnim = {}
+tookRope2Anim = {}
+challengeAnim = {}
+challengeFailedAnim = {}
+challengeCompletedAnim = {}
+beforeKillAnim = {}
+closeCannim = {}
+cannKilledAnim = {}
+cannKilledEarlyAnim = {}
+princessDamagedAnim = {}
+elderDamagedAnim = {}
+pastMoleHeadAnim = {}
+
+
+targets = {}
+crates = {}
+targXdif2 = {2755, 2638, 2921, 2973, 3162, 3067, 3062, 1300}
+targYdif2 = {1197, 1537, 1646, 1857, 1804, 1173, 1167, 1183}
+targXdif1 = {2749, 2909, 2770, 2836, 1558, 1305}
+targYdif1 = {1179, 1313, 1734, 1441, 1152, 1259}
+targetPosX = {{821, 866, 789}, {614, 656, 638}, {1238, 1237, 1200}}
+targetPosY = {{1342, 1347, 1326}, {1112, 1121, 1061}, {1152, 1111, 1111}}
+crateNum = {6, 8}
+
+
+stage = 1
+cratesCollected = 0
+chalTries = 0
+targetsDestroyed = 0
+targsWave = 1
+tTime = -1
+difficulty = 0
+
+cannibalVisible = false
+cannibalKilles = false
+youngdamaged = false
+youngKilled = false
+elderDamaged = false
+princessDamaged = false
+elderKilled = false
+princessKilled = false
+rope1Taken = false
+paraTaken = false
+rope2Taken = false
+punchTaken = false
+canKilled = false
+desertTaken = false
+challengeFailed = false
+deleteCrate = false
+difficultyChoice = false
+princessFace = "Left"
+elderFace = "Left"
+
+goals = {
+ [startDialogue] = {loc("First Blood"), loc("First Steps"), loc("Press [Left] or [Right] to move around, [Enter] to jump"), 1, 4000},
+ [onShroomAnim] = {loc("First Blood"), loc("A leap in a leap"), loc("Go on top of the flower"), 1, 4000},
+ [onFlowerAnim] = {loc("First Blood"), loc("Hightime"), loc("Collect the crate on the right.|Hint: Select the rope, [Up] or [Down] to aim, [Space] to fire, directional keys to move.|Ropes can be fired again in the air!"), 1, 7000},
+ [tookParaAnim] = {loc("First Blood"), loc("Omnivore"), loc("Get on the head of the mole"), 1, 4000},
+ [onMoleHeadAnim] = {loc("First Blood"), loc("The Leap of Faith"), loc("Use the parachute ([Space] while in air) to get the next crate"), 1, 4000},
+ [tookRope2Anim] = {loc("First Blood"), loc("The Rising"), loc("Do the deed"), 1, 4000},
+ [tookPunchAnim] = {loc("First Blood"), loc("The Slaughter"), loc("Destroy the targets!|Hint: Select the Shoryuken and hit [Space]|P.S. You can use it mid-air."), 1, 5000},
+ [challengeAnim] = {loc("First Blood"), loc("The Crate Frenzy"), loc("Collect the crates within the time limit!|If you fail, you'll have to try again."), 1, 5000},
+ [challengeFailedAnim] = {loc("First Blood"), loc("The Crate Frenzy"), loc("Collect the crates within the time limit!|If you fail, you'll have to try again."), 1, 5000},
+ [challengeCompletedAnim] = {loc("First Blood"), loc("The Ultimate Weapon"), loc("Destroy the targets!|Hint: [Up], [Down] to aim, [Space] to shoot"), 1, 5000},
+ [beforeKillAnim] = {loc("First Blood"), loc("The First Blood"), loc("Kill the cannibal!"), 1, 5000},
+ [closeCannim] = {loc("First Blood"), loc("The First Blood"), loc("KILL IT!"), 1, 5000}
+}
+-----------------------------Animations--------------------------------
+function Skipanim(anim)
+ AnimSwitchHog(youngh)
+ if goals[anim] ~= nil then
+ ShowMission(unpack(goals[anim]))
+ end
+ if anim == startDialogue then
+ HogTurnLeft(princess, false)
+ end
+end
+
+function SkipDamageAnim(anim)
+ SwitchHog(youngh)
+ SetInputMask(0xFFFFFFFF)
+end
+
+function SkipOnShroom()
+ Skipanim(onShroomAnim)
+ AnimSetGearPosition(elderh, 2700, 1278)
+end
+
+function AnimationSetup()
+ AddSkipFunction(damageAnim, SkipDamageAnim, {damageAnim})
+ table.insert(damageAnim, {func = AnimWait, args = {youngh, 500}, skipFunc = Skipanim, skipArgs = damageAnim})
+ table.insert(damageAnim, {func = AnimSay, args = {elderh, loc("Watch your steps, young one!"), SAY_SAY, 2000}})
+ table.insert(damageAnim, {func = AnimGearWait, args = {youngh, 500}})
+
+ AddSkipFunction(princessDamagedAnim, SkipDamageAnim, {princessDamagedAnim})
+ table.insert(princessDamagedAnim, {func = AnimWait, args = {princess, 500}, skipFunc = Skipanim, skipArgs = princessDamagedAnim})
+ table.insert(princessDamagedAnim, {func = AnimSay, args = {princess, loc("Why do men keep hurting me?"), SAY_THINK, 3000}})
+ table.insert(princessDamagedAnim, {func = AnimGearWait, args = {youngh, 500}})
+
+ AddSkipFunction(elderDamagedAnim, SkipDamageAnim, {elderDamagedAnim})
+ table.insert(elderDamagedAnim, {func = AnimWait, args = {elderh, 500}, skipFunc = Skipanim, skipArgs = elderDamagedAnim})
+ table.insert(elderDamagedAnim, {func = AnimSay, args = {elderh, loc("Violence is not the answer to your problems!"), SAY_SAY, 3000}})
+ table.insert(elderDamagedAnim, {func = AnimGearWait, args = {youngh, 500}})
+
+ AddSkipFunction(startDialogue, Skipanim, {startDialogue})
+ table.insert(startDialogue, {func = AnimWait, args = {youngh, 3500}, skipFunc = Skipanim, skipArgs = startDialogue})
+ table.insert(startDialogue, {func = AnimCaption, args = {youngh, loc("Once upon a time, on an island with great natural resources, lived two tribes in heated conflict..."), 5000}})
+ table.insert(startDialogue, {func = AnimCaption, args = {youngh, loc("One tribe was peaceful, spending their time hunting and training, enjoying the small pleasures of life..."), 5000}})
+ table.insert(startDialogue, {func = AnimCaption, args = {youngh, loc("The other one were all cannibals, spending their time eating the organs of fellow hedgehogs..."), 5000}})
+ table.insert(startDialogue, {func = AnimCaption, args = {youngh, loc("And so it began..."), 1000}})
+ table.insert(startDialogue, {func = AnimSay, args = {elderh, loc("What are you doing at a distance so great, young one?"), SAY_SHOUT, 4000}})
+ table.insert(startDialogue, {func = AnimSay, args = {elderh, loc("Come closer, so that your training may continue!"), SAY_SHOUT, 6000}})
+ table.insert(startDialogue, {func = AnimSay, args = {youngh, loc("This is it! It's time to make Fell From Heaven fall for me..."), SAY_THINK, 6000}})
+ table.insert(startDialogue, {func = AnimJump, args = {youngh, "long"}})
+ table.insert(startDialogue, {func = AnimTurn, args = {princess, "Right"}})
+ table.insert(startDialogue, {func = AnimSwitchHog, args = {youngh}})
+ table.insert(startDialogue, {func = AnimShowMission, args = {youngh, loc("First Blood"), loc("First Steps"), loc("Press [Left] or [Right] to move around, [Enter] to jump"), 1, 4000}})
+
+ AddSkipFunction(onShroomAnim, SkipOnShroom, {onShroomAnim})
+ table.insert(onShroomAnim, {func = AnimSay, args = {elderh, loc("I can see you have been training diligently."), SAY_SAY, 4000}, skipFunc = Skipanim, skipArgs = onShroomAnim})
+ table.insert(onShroomAnim, {func = AnimSay, args = {elderh, loc("The wind whispers that you are ready to become familiar with tools, now..."), SAY_SAY, 4000}})
+ table.insert(onShroomAnim, {func = AnimSay, args = {elderh, loc("Open that crate and we will continue!"), SAY_SAY, 5000}})
+ table.insert(onShroomAnim, {func = AnimMove, args = {elderh, "Right", 2700, 0}})
+ table.insert(onShroomAnim, {func = AnimTurn, args = {elderh, "Left"}})
+ table.insert(onShroomAnim, {func = AnimSay, args = {princess, loc("He moves like an eagle in the sky."), SAY_THINK, 4000}})
+ table.insert(onShroomAnim, {func = AnimSwitchHog, args = {youngh}})
+ table.insert(onShroomAnim, {func = AnimShowMission, args = {youngh, loc("First Blood"), loc("A leap in a leap"), loc("Go on top of the flower"), 1, 4000}})
+
+ AddSkipFunction(onFlowerAnim, Skipanim, {onFlowerAnim})
+ table.insert(onFlowerAnim, {func = AnimSay, args = {elderh, loc("See that crate farther on the right?"), SAY_SAY, 4000}})
+ table.insert(onFlowerAnim, {func = AnimSay, args = {elderh, loc("Swing, Leaks A Lot, on the wings of the wind!"), SAY_SAY, 6000}})
+ table.insert(onFlowerAnim, {func = AnimSay, args = {princess, loc("His arms are so strong!"), SAY_THINK, 4000}})
+ table.insert(onFlowerAnim, {func = AnimSwitchHog, args = {youngh}})
+ table.insert(onFlowerAnim, {func = AnimShowMission, args = {youngh, loc("First Blood"), loc("Hightime"), loc("Collect the crate on the right.|Hint: Select the rope, [Up] or [Down] to aim, [Space] to fire, directional keys to move.|Ropes can be fired again in the air!"), 1, 7000}})
+
+ AddSkipFunction(tookParaAnim, Skipanim, {tookParaAnim})
+ table.insert(tookParaAnim, {func = AnimGearWait, args = {youngh, 1000}, skipFunc = Skipanim, skipArgs = tookParaAnim})
+ table.insert(tookParaAnim, {func = AnimSay, args = {elderh, loc("Use the rope to get on the head of the mole, young one!"), SAY_SHOUT, 4000}})
+ table.insert(tookParaAnim, {func = AnimSay, args = {elderh, loc("Worry not, for it is a peaceful animal! There is no reason to be afraid..."), SAY_SHOUT, 5000}})
+ table.insert(tookParaAnim, {func = AnimSay, args = {elderh, loc("We all know what happens when you get frightened..."), SAY_SAY, 4000}})
+ table.insert(tookParaAnim, {func = AnimSay, args = {youngh, loc("So humiliating..."), SAY_SAY, 4000}})
+ table.insert(tookParaAnim, {func = AnimShowMission, args = {youngh, loc("First Blood"), loc("Omnivore"), loc("Get on the head of the mole"), 1, 4000}})
+ table.insert(tookParaAnim, {func = AnimSwitchHog, args = {youngh}})
+
+ AddSkipFunction(onMoleHeadAnim, Skipanim, {onMoleHeadAnim})
+ table.insert(onMoleHeadAnim, {func = AnimSay, args = {elderh, loc("Perfect! Now try to get the next crate without hurting yourself!"), SAY_SAY, 4000}, skipFunc = Skipanim, skipArgs = onMoleHeadAnim})
+ table.insert(onMoleHeadAnim, {func = AnimSay, args = {elderh, loc("The giant umbrella from the last crate should help break the fall."), SAY_SAY, 4000}})
+ table.insert(onMoleHeadAnim, {func = AnimSay, args = {princess, loc("He's so brave..."), SAY_THINK, 4000}})
+ table.insert(onMoleHeadAnim, {func = AnimShowMission, args = {youngh, loc("First Blood"), loc("The Leap of Faith"), loc("Use the parachute ([Space] while in air) to get the next crate"), 1, 4000}})
+ table.insert(onMoleHeadAnim, {func = AnimSwitchHog, args = {youngh}})
+
+ AddSkipFunction(pastMoleHeadAnim, Skipanim, {pastMoleHeadAnim})
+ table.insert(pastMoleHeadAnim, {func = AnimSay, args = {elderh, loc("I see you have already taken the leap of faith."), SAY_SAY, 4000}, skipFunc = Skipanim, skipArgs = pastMoleHeadAnim})
+ table.insert(pastMoleHeadAnim, {func = AnimSay, args = {elderh, loc("Get that crate!"), SAY_SAY, 4000}})
+ table.insert(pastMoleHeadAnim, {func = AnimSwitchHog, args = {youngh}})
+
+ AddSkipFunction(tookRope2Anim, Skipanim, {tookRope2Anim})
+ table.insert(tookRope2Anim, {func = AnimSay, args = {elderh, loc("Impressive...you are still dry as the corpse of a hawk after a week in the desert..."), SAY_SAY, 5000}, skipFunc = Skipanim, skipArgs = tookRope2Anim})
+ table.insert(tookRope2Anim, {func = AnimSay, args = {elderh, loc("You probably know what to do next..."), SAY_SAY, 4000}})
+ table.insert(tookRope2Anim, {func = AnimShowMission, args = {youngh, loc("First Blood"), loc("The Rising"), loc("Do the deed"), 1, 4000}})
+ table.insert(tookRope2Anim, {func = AnimSwitchHog, args = {youngh}})
+
+ AddSkipFunction(tookPunchAnim, Skipanim, {tookPunchAnim})
+ table.insert(tookPunchAnim, {func = AnimSay, args = {elderh, loc("It is time to practice your fighting skills."), SAY_SAY, 4000}})
+ table.insert(tookPunchAnim, {func = AnimSay, args = {elderh, loc("Imagine those targets are the wolves that killed your parents! Take your anger out on them!"), SAY_SAY, 5000}})
+ table.insert(tookPunchAnim, {func = AnimShowMission, args = {youngh, loc("First Blood"), loc("The Slaughter"), loc("Destroy the targets!|Hint: Select the Shoryuken and hit [Space]|P.S. You can use it mid-air."), 1, 5000}})
+ table.insert(tookPunchAnim, {func = AnimSwitchHog, args = {youngh}})
+
+ AddSkipFunction(challengeAnim, Skipanim, {challengeAnim})
+ table.insert(challengeAnim, {func = AnimSay, args = {elderh, loc("I hope you are prepared for a small challenge, young one."), SAY_SAY, 4000}, skipFunc = Skipanim, skipArgs = challengeAnim})
+ table.insert(challengeAnim, {func = AnimSay, args = {elderh, loc("Your movement skills will be evaluated now."), SAY_SAY, 4000}})
+ table.insert(challengeAnim, {func = AnimSay, args = {elderh, loc("Collect all the crates, but remember, our time in this life is limited!"), SAY_SAY, 4000}})
+ table.insert(challengeAnim, {func = AnimSay, args = {elderh, loc("How difficult would you like it to be?")}})
+ table.insert(challengeAnim, {func = AnimSwitchHog, args = {youngh}})
+ table.insert(challengeAnim, {func = AnimWait, args = {youngh, 500}})
+
+ AddSkipFunction(challengeFailedAnim, Skipanim, {challengeFailedAnim})
+ table.insert(challengeFailedAnim, {func = AnimSay, args = {elderh, loc("Hmmm...perhaps a little more time will help."), SAY_SAY, 4000}, skipFunc = Skipanim, skipArgs = challengeFailedAnim})
+ table.insert(challengeFailedAnim, {func = AnimShowMission, args = {youngh, loc("First Blood"), loc("The Crate Frenzy"), loc("Collect the crates within the time limit!|If you fail, you'll have to try again."), 1, 5000}})
+ table.insert(challengeFailedAnim, {func = AnimSwitchHog, args = {youngh}})
+
+ AddSkipFunction(challengeCompletedAnim, Skipanim, {challengeCompletedAnim})
+ table.insert(challengeCompletedAnim, {func = AnimSay, args = {elderh, loc("The spirits of the ancerstors are surely pleased, Leaks A Lot."), SAY_SAY, 4000}, skipFunc = Skipanim, skipArgs = challengeCompletedAnim})
+ table.insert(challengeCompletedAnim, {func = AnimSay, args = {elderh, loc("You have proven yourself worthy to see our most ancient secret!"), SAY_SAY, 4000}})
+ table.insert(challengeCompletedAnim, {func = AnimSay, args = {elderh, loc("The weapon in that last crate was bestowed upon us by the ancients!"), SAY_SAY, 4000}})
+ table.insert(challengeCompletedAnim, {func = AnimSay, args = {elderh, loc("Use it with precaution!"), SAY_SAY, 4000}})
+ table.insert(challengeCompletedAnim, {func = AnimShowMission, args = {youngh, loc("First Blood"), loc("The Ultimate Weapon"), loc("Destroy the targets!|Hint: [Up], [Down] to aim, [Space] to shoot"), 1, 5000}})
+ table.insert(challengeCompletedAnim, {func = AnimSwitchHog, args = {youngh}})
+
+ AddSkipFunction(beforeKillAnim, Skipanim, {beforeKillAnim})
+ table.insert(beforeKillAnim, {func = AnimSay, args = {elderh, loc("What do my faulty eyes observe? A spy!"), SAY_SHOUT, 4000}, skipFunc = Skipanim, skipArgs = beforeKillAnim})
+ table.insert(beforeKillAnim, {func = AnimFollowGear, args = {cannibal}})
+ table.insert(beforeKillAnim, {func = AnimWait, args = {cannibal, 1000}})
+ table.insert(beforeKillAnim, {func = AnimSay, args = {elderh, loc("Destroy him, Leaks A Lot! He is responsible for the deaths of many of us!"), SAY_SHOUT, 4000}})
+ table.insert(beforeKillAnim, {func = AnimSay, args = {cannibal, loc("Oh, my!"), SAY_THINK, 4000}})
+ table.insert(beforeKillAnim, {func = AnimShowMission, args = {youngh, loc("First Blood"), loc("The First Blood"), loc("Kill the cannibal!"), 1, 5000}})
+ table.insert(beforeKillAnim, {func = AnimSwitchHog, args = {youngh}})
+
+ AddSkipFunction(closeCannim, Skipanim, {closeCannim})
+ table.insert(closeCannim, {func = AnimSay, args = {elderh, loc("I see you would like his punishment to be more...personal..."), SAY_SAY, 4000}, skipFunc = Skipanim, skipArgs = closeCannim})
+ table.insert(closeCannim, {func = AnimSay, args = {cannibal, loc("I'm certain that this is a misunderstanding, fellow hedgehogs!"), SAY_SAY, 4000}})
+ table.insert(closeCannim, {func = AnimSay, args = {cannibal, loc("If only I were given a chance to explain my being here..."), SAY_SAY, 4000}})
+ table.insert(closeCannim, {func = AnimSay, args = {elderh, loc("Do not let his words fool you, young one! He will stab you in the back as soon as you turn away!"), SAY_SAY, 6000}})
+ table.insert(closeCannim, {func = AnimSay, args = {elderh, loc("Here...pick your weapon!"), SAY_SAY, 5000}})
+ table.insert(closeCannim, {func = AnimShowMission, args = {youngh, loc("First Blood"), loc("The First Blood"), loc("KILL IT!"), 1, 5000}})
+ table.insert(closeCannim, {func = AnimSwitchHog, args = {youngh}})
+
+ table.insert(cannKilledAnim, {func = AnimSay, args = {elderh, loc("Yes, yeees! You are now ready to enter the real world!"), SAY_SHOUT, 6000}})
+
+ table.insert(cannKilledEarlyAnim, {func = AnimSay, args = {elderh, loc("What?! A cannibal? Here? There is no time to waste! Come, you are prepared."), SAY_SHOUT, 4000}})
+end
+-----------------------------Events------------------------------------
+function CheckNeedToTurn(gear)
+ if youngKilled then
+ return false
+ end
+ if gear == princess then
+ if princessKilled ~= true then
+ if (GetX(princess) > GetX(youngh) and princessFace == "Right")
+ or (GetX(princess) < GetX(youngh) and princessFace == "Left") then
+ --if (GetX(princess) > GetX(youngh))
+ -- or (GetX(princess) < GetX(youngh)) then
+ return true
+ end
+ end
+ else
+ if elderKilled ~= true then
+ if (GetX(elderh) > GetX(youngh) and elderFace == "Right")
+ or (GetX(elderh) < GetX(youngh) and elderFace == "Left") then
+ return true
+ end
+ end
+ end
+ return false
+end
+
+function DoNeedToTurn(gear)
+ if gear == princess then
+ if GetX(princess) > GetX(youngh) then
+ HogTurnLeft(princess, true)
+ princessFace = "Left"
+ elseif GetX(princess) < GetX(youngh) then
+ HogTurnLeft(princess, false)
+ princessFace = "Right"
+ end
+ else
+ if GetX(elderh) > GetX(youngh) then
+ HogTurnLeft(elderh, true)
+ elderFace = "Left"
+ elseif GetX(elderh) < GetX(youngh) then
+ HogTurnLeft(elderh, false)
+ elderFace = "Right"
+ end
+ end
+end
+
+function CheckDamage()
+ return youngdamaged and StoppedGear(youngh)
+end
+
+function DoOnDamage()
+ AddAnim(damageAnim)
+ youngdamaged = false
+ AddFunction({func = ResetTurnTime, args = {}})
+end
+
+function CheckDeath()
+ return youngKilled
+end
+
+function DoDeath()
+ RemoveEventFunc(CheckKilledOthers)
+ RemoveEventFunc(CheckDamage)
+ RemoveEventFunc(CheckDamagedOthers)
+ FinishThem()
+ ShowMission(loc("First Blood"), loc("The wasted youth"), loc("Leaks A Lot gave his life for his tribe! He should have survived!"), 2, 4000)
+end
+
+function CheckDamagedOthers()
+ return (princessDamaged and StoppedGear(princess)) or (elderDamaged and StoppedGear(elderh))
+end
+
+function CheckKilledOthers()
+ return princessKilled or elderKilled
+end
+
+function DoOnDamagedOthers()
+ if princessDamaged then
+ AddAnim(princessDamagedAnim)
+ end
+ if elderDamaged then
+ AddAnim(elderDamagedAnim)
+ end
+ elderDamaged = false
+ princessDamaged = false
+ AddFunction({func = ResetTurnTime, args = {}})
+end
+
+function DoKilledOthers()
+ AddCaption(loc("After Leaks A Lot betrayed his tribe, he joined the cannibals..."))
+ FinishThem()
+end
+
+function CheckMovedUntilJump()
+ return GetX(youngh) >= 2343
+end
+
+function DoMovedUntilJump()
+ ShowMission(loc("First Blood"), loc("Step By Step"), loc("Hint: Double Jump - Press [Backspace] twice"), -amSkip, 0)
+ AddEvent(CheckOnShroom, {}, DoOnShroom, {}, 0)
+end
+
+function CheckOnShroom()
+ return GetX(youngh) >= 2461 and StoppedGear(youngh)
+end
+
+function DoOnShroom()
+ ropeCrate1 = SpawnUtilityCrate(2751, 1194, amRope)
+ SetGearMessage(CurrentHedgehog, 0)
+ AddAnim(onShroomAnim)
+ AddEvent(CheckOnFlower, {}, DoOnFlower, {}, 0)
+end
+
+function CheckOnFlower()
+ return rope1Taken and StoppedGear(youngh)
+end
+
+function DoOnFlower()
+ AddAmmo(youngh, amRope, 100)
+ paraCrate = SpawnUtilityCrate(3245, 1758, amParachute)
+ SetGearMessage(CurrentHedgehog, 0)
+ AddAnim(onFlowerAnim)
+ AddEvent(CheckTookParaCrate, {}, DoTookParaCrate, {}, 0)
+end
+
+function CheckTookParaCrate()
+ return paraTaken and StoppedGear(youngh)
+end
+
+function DoTookParaCrate()
+ AddAmmo(youngh, amParachute, 100)
+ SetGearMessage(CurrentHedgehog, 0)
+ AddAnim(tookParaAnim)
+ AddEvent(CheckOnMoleHead, {}, DoOnMoleHead, {}, 0)
+ AddEvent(CheckPastMoleHead, {}, DoPastMoleHead, {}, 0)
+end
+
+function CheckOnMoleHead()
+ x = GetX(youngh)
+ return x >= 3005 and x <= 3126 and StoppedGear(youngh)
+end
+
+function CheckPastMoleHead()
+ x = GetX(youngh)
+ y = GetY(youngh)
+ return x < 3005 and y > 1500 and StoppedGear(youngh)
+end
+
+function DoPastMoleHead()
+ RemoveEventFunc(CheckOnMoleHead)
+ ropeCrate2 = SpawnUtilityCrate(2782, 1720, amRope)
+ AddAmmo(youngh, amRope, 0)
+ SetGearMessage(CurrentHedgehog, 0)
+ AddAnim(pastMoleHeadAnim)
+ AddEvent(CheckTookRope2, {}, DoTookRope2, {}, 0)
+end
+
+function DoOnMoleHead()
+ RemoveEventFunc(CheckPastMoleHead)
+ ropeCrate2 = SpawnUtilityCrate(2782, 1720, amRope)
+ AddAmmo(youngh, amRope, 0)
+ SetGearMessage(CurrentHedgehog, 0)
+ AddAnim(onMoleHeadAnim)
+ AddEvent(CheckTookRope2, {}, DoTookRope2, {}, 0)
+end
+
+function CheckTookRope2()
+ return rope2Taken and StoppedGear(youngh)
+end
+
+function DoTookRope2()
+ AddAmmo(youngh, amRope, 100)
+ SetGearMessage(CurrentHedgehog, 0)
+ AddAnim(tookRope2Anim)
+ punchCrate = SpawnAmmoCrate(2460, 1321, amFirePunch)
+ AddEvent(CheckTookPunch, {}, DoTookPunch, {})
+end
+
+function CheckTookPunch()
+ return punchTaken and StoppedGear(youngh)
+end
+
+function DoTookPunch()
+ AddAmmo(youngh, amFirePunch, 100)
+ AddAmmo(youngh, amRope, 0)
+ SetGearMessage(CurrentHedgehog, 0)
+ AddAnim(tookPunchAnim)
+ targets[1] = AddGear(1594, 1185, gtTarget, 0, 0, 0, 0)
+ targets[2] = AddGear(2188, 1314, gtTarget, 0, 0, 0, 0)
+ targets[3] = AddGear(1961, 1318, gtTarget, 0, 0, 0, 0)
+ targets[4] = AddGear(1961, 1200, gtTarget, 0, 0, 0, 0)
+ targets[5] = AddGear(1800, 900, gtTarget, 0, 0, 0, 0)
+ AddEvent(CheckTargDestroyed, {}, DoTargDestroyed, {}, 0)
+end
+
+function CheckTargDestroyed()
+ return targetsDestroyed == 5 and StoppedGear(youngh)
+end
+
+function DoTargDestroyed()
+ SetGearMessage(CurrentHedgehog, 0)
+ AddAnim(challengeAnim)
+ targetsDestroyed = 0
+ AddFunction({func = SetChoice, args = {}})
+ ropeCrate3 = SpawnAmmoCrate(2000, 1200, amRope)
+ AddEvent(CheckTookRope3, {}, AddAmmo, {youngh, amRope, 100}, 0)
+ AddEvent(CheckCratesColled, {}, DoCratesColled, {}, 0)
+ AddEvent(CheckChallengeWon, {}, DoChallengeWon, {}, 0)
+ AddEvent(CheckTimesUp, {}, DoTimesUp, {}, 1)
+end
+
+function CheckChoice()
+ return difficulty ~= 0
+end
+
+function DoChoice()
+ difficultyChoice = false
+ SetInputMask(0xFFFFFFFF)
+ StartChallenge(120000 + chalTries * 20000)
+end
+
+function CheckCratesColled()
+ return cratesCollected == crateNum[difficulty]
+end
+
+function DoCratesColled()
+ RemoveEventFunc(CheckTimesUp)
+ TurnTimeLeft = -1
+ AddCaption(loc("As the challenge was completed, Leaks A Lot set foot on the ground..."))
+end
+
+function CheckChallengeWon()
+ return cratesCollected == crateNum[difficulty] and StoppedGear(youngh)
+end
+
+function DoChallengeWon()
+ desertCrate = SpawnAmmoCrate(1240, 1212, amDEagle)
+ SetGearMessage(CurrentHedgehog, 0)
+ AddAnim(challengeCompletedAnim)
+ AddEvent(CheckDesertColled, {}, DoDesertColled, {}, 0)
+end
+
+function CheckTookRope3()
+ return rope3Taken
+end
+
+function CheckTimesUp()
+ return TurnTimeLeft == 100
+end
+
+function DoTimesUp()
+ challengeFailed = true
+ deleteCrate = true
+ DeleteGear(crates[1])
+ TurnTimeLeft = -1
+ AddCaption(loc("And so happenned that Leaks A Lot failed to complete the challenge! He landed, pressured by shame..."))
+ AddEvent(CheckChallengeFailed, {}, DoChallengeFailed, {}, 0)
+end
+
+function CheckChallengeFailed()
+ return challengeFailed and StoppedGear(youngh)
+end
+
+function DoChallengeFailed()
+ challengeFailed = false
+ SetGearMessage(CurrentHedgehog, 0)
+ AddAnim(challengeFailedAnim)
+ chalTries = chalTries + 1
+ difficulty = 0
+ AddFunction({func = SetChoice, args = {}})
+end
+
+function CheckDesertColled()
+ return desertTaken and StoppedGear(youngh)
+end
+
+function DoDesertColled()
+ AddAmmo(youngh, amDEagle, 100)
+ PutTargets(1)
+ AddEvent(CheckTargetsKilled, {}, DoTargetsKilled, {}, 1)
+ AddEvent(CheckCannibalKilled, {}, DoCannibalKilledEarly, {}, 0)
+ ShowMission(loc("First Blood"), loc("The Bull's Eye"), loc("[Up], [Down] to aim, [Space] to shoot!"), 1, 5000)
+end
+
+function CheckTargetsKilled()
+ return targetsDestroyed == 3 and StoppedGear(youngh)
+end
+
+function DoTargetsKilled()
+ targetsDestroyed = 0
+ targsWave = targsWave + 1
+ if targsWave > 3 then
+ RemoveEventFunc(CheckTargetsKilled)
+ SetState(cannibal, gstVisible)
+ cannibalVisible = true
+ SetGearMessage(CurrentHedgehog, 0)
+ AddAnim(beforeKillAnim)
+ AddEvent(CheckCloseToCannibal, {}, DoCloseToCannibal, {}, 0)
+ AddEvent(CheckCannibalKilled, {}, DoCannibalKilled, {}, 0)
+ else
+ PutTargets(targsWave)
+ end
+end
+
+function CheckCloseToCannibal()
+ if CheckCannibalKilled() then
+ return false
+ end
+ return math.abs(GetX(cannibal) - GetX(youngh)) <= 400 and StoppedGear(youngh)
+end
+
+function DoCloseToCannibal()
+ SetGearMessage(CurrentHedgehog, 0)
+ AddAnim(closeCannim)
+ AddFunction({func = SpawnAmmoCrate, args = {targetPosX[1][1], targetPosY[1][1], amWhip}})
+ AddFunction({func = SpawnAmmoCrate, args = {targetPosX[1][2], targetPosY[1][2], amBaseballBat}})
+ AddFunction({func = SpawnAmmoCrate, args = {targetPosX[1][3], targetPosY[1][3], amHammer}})
+end
+
+function CheckCannibalKilled()
+ return cannibalKilled and StoppedGear(youngh)
+end
+
+function DoCannibalKilled()
+ AddAnim(cannKilledAnim)
+ if not progress then
+ SaveCampaignVar("Progress", "1")
+ end
+end
+
+function DoCannibalKilledEarly()
+ AddAnim(cannKilledEarlyAnim)
+ DoCannibalKilled()
+end
+
+-----------------------------Misc--------------------------------------
+function StartChallenge(time)
+ cratesCollected = 0
+ PutCrate(1)
+ TurnTimeLeft = time
+ ShowMission(loc("First Blood"), loc("The Crate Frenzy"), loc("Collect the crates within the time limit!|If you fail, you'll have to try again."), 1, 5000)
+end
+
+function SetChoice()
+ SetInputMask(band(0xFFFFFFFF, bnot(gmAnimate+gmAttack+gmDown+gmHJump+gmLJump+gmSlot+gmSwitch+gmTimer+gmUp+gmWeapon)))
+ difficultyChoice = true
+ ShowMission(loc("First Blood"), loc("The Torment"), loc("Select difficulty: [Left] - easier or [Right] - harder"), 0, 4000)
+ AddEvent(CheckChoice, {}, DoChoice, {}, 0)
+end
+
+function SetTime(time)
+ TurnTimeLeft = time
+end
+
+function ResetTurnTime()
+ TurnTimeLeft = tTime
+ tTime = -1
+end
+
+function PutCrate(i)
+ if i > crateNum[difficulty] then
+ return
+ end
+ if difficulty == 1 then
+ crates[1] = SpawnAmmoCrate(targXdif1[i], targYdif1[i], amRope)
+ else
+ crates[1] = SpawnAmmoCrate(targXdif2[i], targYdif2[i], amRope)
+ end
+end
+
+function PutTargets(i)
+ targets[1] = AddGear(targetPosX[i][1], targetPosY[i][1], gtTarget, 0, 0, 0, 0)
+ targets[2] = AddGear(targetPosX[i][2], targetPosY[i][2], gtTarget, 0, 0, 0, 0)
+ targets[3] = AddGear(targetPosX[i][3], targetPosY[i][3], gtTarget, 0, 0, 0, 0)
+end
+
+function FinishThem()
+ SetHealth(elderh, 0)
+ SetHealth(youngh, 0)
+ SetHealth(princess, 0)
+end
+-----------------------------Main Functions----------------------------
+
+function onGameInit()
+ Seed = 69
+ GameFlags = gfInfAttack + gfSolidLand + gfDisableWind
+ TurnTime = 100000
+ CaseFreq = 0
+ MinesNum = 0
+ MinesTime = 3000
+ Explosives = 0
+ Delay = 10
+ Map = "A_Classic_Fairytale_first_blood"
+ Theme = "Nature"
+
+
+ AddTeam(loc("Natives"), 29439, "Bone", "Island", "HillBilly", "cm_birdy")
+ youngh = AddHog(loc("Leaks A Lot"), 0, 100, "Rambo")
+ elderh = AddHog(loc("Righteous Beard"), 0, 99, "IndianChief")
+ princess = AddHog(loc("Fell From Heaven"), 0, 300, "tiara")
+ AnimSetGearPosition(princess, 1911, 1361)
+ HogTurnLeft(princess, true)
+ AnimSetGearPosition(elderh, 2667, 1208)
+ HogTurnLeft(elderh, true)
+ AnimSetGearPosition(youngh, 1862, 1362)
+ HogTurnLeft(youngh, false)
+
+ AddTeam(loc("Cannibals"), 14483456, "Skull", "Island", "Pirate","cm_vampire")
+ cannibal = AddHog(loc("Brainiac"), 0, 5, "Zombi")
+ AnimSetGearPosition(cannibal, 525, 1256)
+ HogTurnLeft(cannibal, false)
+
+ AnimInit()
+ AnimationSetup()
+end
+
+function onGameStart()
+ progress = tonumber(GetCampaignVar("Progress"))
+ TurnTimeLeft = -1
+ FollowGear(youngh)
+ ShowMission(loc("A Classic Fairytale"), loc("First Blood"), loc("Finish your training|Hint: Animations can be skipped with the [Precise] key."), -amSkip, 0)
+ SetState(cannibal, gstInvisible)
+
+ AddAnim(startDialogue)
+ princessFace = "Right"
+ AddEvent(CheckNeedToTurn, {princess}, DoNeedToTurn, {princess}, 1)
+ AddEvent(CheckNeedToTurn, {elderh}, DoNeedToTurn, {elderh}, 1)
+ AddEvent(CheckDamage, {}, DoOnDamage, {}, 1)
+ AddEvent(CheckDeath, {}, DoDeath, {}, 0)
+ AddEvent(CheckDamagedOthers, {}, DoOnDamagedOthers, {}, 1)
+ AddEvent(CheckKilledOthers, {}, DoKilledOthers, {}, 0)
+ AddEvent(CheckMovedUntilJump, {}, DoMovedUntilJump, {}, 0)
+end
+
+function onGameTick()
+ AnimUnWait()
+ if ShowAnimation() == false then
+ return
+ end
+ ExecuteAfterAnimations()
+ CheckEvents()
+end
+
+function onGearDelete(gear)
+ if gear == ropeCrate1 then
+ rope1Taken = true
+ elseif gear == paraCrate then
+ paraTaken = true
+ elseif gear == ropeCrate2 then
+ rope2Taken = true
+ elseif gear == ropeCrate3 then
+ rope3Taken = true
+ elseif gear == crates[1] and deleteCrate == true then
+ deleteCrate = false
+ elseif gear == crates[1] and challengeFailed == false then
+ crates[1] = nil
+ cratesCollected = cratesCollected + 1
+ PutCrate(cratesCollected + 1)
+ elseif gear == punchCrate then
+ punchTaken = true
+ elseif gear == desertCrate then
+ desertTaken = true
+ elseif GetGearType(gear) == gtTarget then
+ i = 1
+ while targets[i] ~= gear do
+ i = i + 1
+ end
+ targets[i] = nil
+ targetsDestroyed = targetsDestroyed + 1
+ elseif gear == cannibal then
+ cannibalKilled = true
+ elseif gear == princess then
+ princessKilled = true
+ elseif gear == elderh then
+ elderKilled = true
+ elseif gear == youngh then
+ youngKilled = true
+ end
+end
+
+function onAmmoStoreInit()
+ SetAmmo(amWhip, 0, 0, 0, 8)
+ SetAmmo(amBaseballBat, 0, 0, 0, 8)
+ SetAmmo(amHammer, 0, 0, 0, 8)
+end
+
+function onNewTurn()
+ if CurrentHedgehog == cannibal and cannibalVisible == false then
+ SetState(cannibal, gstInvisible)
+ end
+ SwitchHog(youngh)
+ FollowGear(youngh)
+ TurnTimeLeft = -1
+end
+
+function onGearDamage(gear, damage)
+ if gear == youngh then
+ youngdamaged = true
+ tTime = TurnTimeLeft
+ elseif gear == princess then
+ princessDamaged = true
+ tTime = TurnTimeLeft
+ elseif gear == elderh then
+ elderDamaged = true
+ tTime = TurnTimeLeft
+ elseif gear == cannibal then
+ cannibalVisible = true
+ cannibalDamaged = true
+ SetState(cannibal, 0)
+ end
+end
+
+function onPrecise()
+ if GameTime > 2000 then
+ SetAnimSkip(true)
+ end
+end
+
+function onLeft()
+ if difficultyChoice == true then
+ difficulty = 1
+ end
+end
+
+function onRight()
+ if difficultyChoice == true then
+ difficulty = 2
+ end
+end
+
Binary file share/hedgewars/Data/Missions/Campaign/A_Classic_Fairytale/journey.hwp has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Missions/Campaign/A_Classic_Fairytale/journey.lua Mon Jul 01 23:23:22 2013 +0300
@@ -0,0 +1,1077 @@
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Animate.lua")
+
+--///////////////////////////////CONSTANTS///////////////////////////
+
+choiceAccepted = 1
+choiceRefused = 2
+choiceAttacked = 3
+
+endStage = 1
+
+cannibalNum = 8
+cannibalNames = {loc("John"), loc("Flesh for Brainz"), loc("Eye Chewer"), loc("Torn Muscle"),
+ loc("Nom-Nom"), loc("Vedgies"), loc("Brain Blower"), loc("Gorkij")}
+cannibalPos = {{2471, 1174}, {939, 1019}, {1953, 902}, {3055, 1041},
+ {1121, 729}, {1150, 718}, {1149, 680}, {1161, 773}}
+
+startLeaksPosDuo = {3572, 1426}
+startEventXDuo = 3300
+startDensePosDuo = {3454, 1471}
+startCyborgPosDuo = {3202, 1307}
+midDensePosDuo = {1464, 1410}
+midCyborgPosDuo = {1264, 1390}
+
+--///////////////////////////////VARIABLES///////////////////////////
+
+m2Choice = 0
+m2DenseDead = 0
+m2RamonDead = 0
+m2SpikyDead = 0
+
+TurnsLeft = 0
+stage = 0
+
+--cyborgHidden = false
+--princessHidden = false
+blowTaken = false
+fireTaken = false
+gravityTaken = false
+sniperTaken = false
+girderTaken = false
+girder1Taken = false
+girder2Taken = false
+leaksDead = false
+denseDead = false
+princessDead = false
+cyborgDead = false
+cannibalDead = {}
+hedgeHidden = {}
+
+startAnim = {}
+startAnimAD = {}
+startAnimAL = {}
+startAnimRL = {}
+
+pastFlowerAnimAL = {}
+pastFlowerAnimRL = {}
+pastFlowerAnim = {}
+
+outPitAnimAL = {}
+outPitAnimRL = {}
+outPitAnim = {}
+
+midAnim = {}
+midAnimAD = {}
+
+failAnim = {}
+failAnimAD = {}
+
+endAnim = {}
+endAnimAD = {}
+endAnimAL = {}
+endAnimRL = {}
+
+endFailAnim = {}
+endFailAnimAD = {}
+
+winAnim = {}
+winAnimAD = {}
+
+--/////////////////////////Animation Functions///////////////////////
+function AfterMidFailAnim()
+ ParseCommand("teamgone " .. loc("Natives"))
+ TurnTimeLeft = 0
+end
+
+function AfterMidAnimAlone()
+ SetupCourse()
+ for i = 5, 8 do
+ RestoreHedge(cannibals[i])
+ AnimSetGearPosition(cannibals[i], unpack(cannibalPos[i]))
+ end
+
+ AddAmmo(cannibals[5], amDEagle, 0)
+
+ AddEvent(CheckGirderTaken, {}, DoGirderTaken, {}, 0)
+ AddEvent(CheckOnFirstGirder, {}, DoOnFirstGirder, {}, 0)
+ AddEvent(CheckTookSniper, {}, DoTookSniper, {}, 0)
+ AddEvent(CheckFailedCourse, {}, DoFailedCourse, {}, 0)
+ SetGearMessage(leaks, 0)
+ TurnsLeft = 12
+ TurnTimeLeft = TurnTime
+ ShowMission(loc("The Journey Back"), loc("Collateral Damage"), loc("Save the princess by collecting the crate in under 12 turns!"), 0, 6000)
+ -----------------------///////////////------------
+ --AnimSetGearPosition(leaks, 417, 1800)
+end
+
+function SkipEndAnimAlone()
+ RestoreHedge(cyborg)
+ RestoreHedge(princess)
+ AnimSetGearPosition(cyborg, 437, 1700)
+ AnimSetGearPosition(princess, 519, 1722)
+end
+
+function SkipEndAnimDuo()
+ RestoreHedge(cyborg)
+ RestoreHedge(princess)
+ if princessHidden then
+ RestoreHog(princess)
+ princessHidden = false
+ end
+ AnimSetGearPosition(cyborg, 437, 1700)
+ AnimSetGearPosition(princess, 519, 1722)
+ AnimSetGearPosition(leaks, 763, 1760)
+ AnimSetGearPosition(dense, 835, 1519)
+ HogTurnLeft(leaks, true)
+ HogTurnLeft(dense, true)
+end
+
+function AfterEndAnimAlone()
+ stage = endStage
+ SwitchHog(leaks)
+ SetGearMessage(leaks, 0)
+ TurnTimeLeft = -1
+ ShowMission(loc("The Journey Back"), loc("Collateral Damage II"), loc("Save Fell From Heaven!"), 1, 4000)
+ AddEvent(CheckLost, {}, DoLost, {}, 0)
+ AddEvent(CheckWon, {}, DoWon, {}, 0)
+ RemoveEventFunc(CheckFailedCourse)
+end
+
+function AfterEndAnimDuo()
+ stage = endStage
+ SwitchHog(leaks)
+ SetGearMessage(leaks, 0)
+ SetGearMessage(dense, 0)
+ TurnTimeLeft = -1
+ ShowMission(loc("The Journey Back"), loc("Collateral Damage II"), loc("Save Fell From Heaven!"), 1, 4000)
+ AddEvent(CheckLost, {}, DoLost, {}, 0)
+ AddEvent(CheckWon, {}, DoWon, {}, 0)
+end
+
+function SkipMidAnimAlone()
+ AnimSetGearPosition(leaks, 2656, 1842)
+ AnimSwitchHog(leaks)
+ SetInputMask(0xFFFFFFFF)
+ AnimWait(dense, 1)
+ AddFunction({func = HideHedge, args = {princess}})
+ AddFunction({func = HideHedge, args = {cyborg}})
+end
+
+function AfterStartAnim()
+ SetGearMessage(leaks, 0)
+ TurnTimeLeft = TurnTime
+ local goal = loc("Get the crate on the other side of the island!|")
+ local hint = loc("Hint: you might want to stay out of sight and take all the crates...|")
+ local stuck = loc("If you get stuck, use your Desert Eagle or restart the mission!|")
+ local conds = loc("Leaks A Lot must survive!")
+ if m2DenseDead == 0 then
+ conds = loc("Your hogs must survive!")
+ end
+ ShowMission(loc("The Journey Back"), loc("Adventurous"), goal .. hint .. stuck .. conds, 0, 7000)
+end
+
+function SkipStartAnim()
+ AnimSwitchHog(leaks)
+end
+
+function PlaceCratesDuo()
+ SpawnAmmoCrate(3090, 827, amBaseballBat)
+ girderCrate1 = SpawnUtilityCrate(2466, 1814, amGirder)
+ girderCrate2 = SpawnUtilityCrate(2630, 1278, amGirder)
+ SpawnUtilityCrate(2422, 1810, amParachute)
+ SpawnUtilityCrate(3157, 1009, amLowGravity)
+ sniperCrate = SpawnAmmoCrate(784, 1715, amSniperRifle)
+end
+
+function PlaceMinesDuo()
+ SetTimer(AddGear(2920, 1448, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2985, 1338, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(3005, 1302, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(3030, 1270, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(3046, 1257, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2954, 1400, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2967, 1385, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2849, 1449, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2811, 1436, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2773, 1411, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2732, 1390, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2700, 1362, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2642, 1321, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2172, 1417, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2190, 1363, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2219, 1332, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(1201, 1207, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(1247, 1205, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(1295, 1212, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(1356, 1209, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(1416, 1201, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(1466, 1201, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(1678, 1198, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(1738, 1198, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(1796, 1198, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(1637, 1217, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(1519, 1213, gtMine, 0, 0, 0, 0), 5000)
+end
+
+function AfterPastFlowerAnim()
+ PlaceMinesDuo()
+ AddEvent(CheckDensePit, {}, DoDensePit, {}, 0)
+ AddEvent(CheckTookGirder1, {}, DoTookGirder1, {}, 0)
+ AddEvent(CheckTookGirder2, {}, DoTookGirder2, {}, 0)
+ SetGearMessage(leaks, 0)
+ SetGearMessage(dense, 0)
+ TurnTimeLeft = 0
+ ShowMission(loc("The Journey Back"), loc("The Savior"), loc("Get Dense Cloud out of the pit!"), 1, 5000)
+end
+
+function SkipPastFlowerAnim()
+ AnimSetGearPosition(dense, 2656, 1842)
+ AnimSwitchHog(dense)
+ AnimWait(dense, 1)
+ AddFunction({func = HideHedge, args = {cyborg}})
+end
+
+function AfterOutPitAnim()
+ SetupCourseDuo()
+ RestoreHedge(cannibals[5])
+ AddAmmo(cannibals[5], amDEagle, 0)
+ HideHedge(cannibals[5])
+ AddEvent(CheckTookFire, {}, DoTookFire, {}, 0)
+ SetGearMessage(leaks, 0)
+ SetGearMessage(dense, 0)
+ TurnTimeLeft = 0
+ ShowMission(loc("The Journey Back"), loc("They never learn"), loc("Free Dense Cloud and continue the mission!"), 1, 5000)
+end
+
+function SkipOutPitAnim()
+ AnimSetGearPosition(dense, unpack(midDensePosDuo))
+ AnimSwitchHog(dense)
+ AnimWait(dense, 1)
+ AddFunction({func = HideHedge, args = {cyborg}})
+end
+
+function RestoreCyborg(x, y, xx, yy)
+ RestoreHedge(cyborg)
+ RestoreHedge(princess)
+ AnimOutOfNowhere(cyborg, x, y)
+ AnimOutOfNowhere(princess, xx, yy)
+ HogTurnLeft(princess, false)
+ return true
+end
+
+function RestoreCyborgOnly(x, y)
+ RestoreHedge(cyborg)
+ SetState(cyborg, 0)
+ AnimOutOfNowhere(cyborg, x, y)
+ return true
+end
+
+function TargetPrincess()
+ ParseCommand("setweap " .. string.char(amDEagle))
+ SetGearMessage(cyborg, gmUp)
+ return true
+end
+
+function HideCyborg()
+ HideHedge(cyborg)
+ HideHedge(princess)
+end
+
+function HideCyborgOnly()
+ HideHedge(cyborg)
+end
+
+function SetupKillRoom()
+ PlaceGirder(2342, 1814, 2)
+ PlaceGirder(2294, 1783, 0)
+ PlaceGirder(2245, 1814, 2)
+end
+
+function SetupCourseDuo()
+ PlaceGirder(1083, 1152, 6)
+ PlaceGirder(1087, 1150, 6)
+ PlaceGirder(1133, 1155, 0)
+ PlaceGirder(1135, 1152, 0)
+ PlaceGirder(1135, 1078, 0)
+ PlaceGirder(1087, 1016, 2)
+ PlaceGirder(1018, 921, 5)
+ PlaceGirder(1016, 921, 5)
+ PlaceGirder(962, 782, 6)
+ PlaceGirder(962, 662, 2)
+ PlaceGirder(962, 661, 2)
+ PlaceGirder(962, 650, 2)
+ PlaceGirder(962, 630, 2)
+ PlaceGirder(1033, 649, 0)
+ PlaceGirder(952, 650, 0)
+
+ fireCrate = SpawnAmmoCrate(1846, 1100, amFirePunch)
+ SpawnUtilityCrate(1900, 1100, amPickHammer)
+ SpawnAmmoCrate(950, 674, amDynamite)
+ SpawnUtilityCrate(994, 825, amRope)
+ SpawnUtilityCrate(570, 1357, amLowGravity)
+end
+
+function DumpMines()
+ SetTimer(AddGear(2261, 1835, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2280, 1831, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2272, 1809, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2290, 1815, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2278, 1815, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2307, 1811, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2286, 1820, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2309, 1813, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2303, 1822, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2317, 1827, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2312, 1816, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2316, 1812, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2307, 1802, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2276, 1818, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2284, 1816, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2292, 1811, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2295, 1814, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2306, 1811, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2292, 1815, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2314, 1815, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2286, 1813, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2275, 1813, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2269, 1814, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2273, 1812, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2300, 1808, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2322, 1812, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2323, 1813, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2311, 1811, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2303, 1809, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2287, 1808, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2282, 1808, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2277, 1809, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2296, 1809, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(2314, 1818, gtMine, 0, 0, 0, 0), 5000)
+end
+
+function SetupAnimRefusedDied()
+ SetupAnimAcceptedDied()
+ table.insert(startAnim, {func = AnimSay, args = {leaks, loc("I just wonder where Ramon and Spiky disappeared..."), SAY_THINK, 6000}})
+end
+
+function SetupAnimAttacked()
+ SetupAnimAcceptedDied()
+ startAnim = {}
+ table.insert(startAnim, {func = AnimWait, args = {leaks, 3000}})
+ table.insert(startAnim, {func = AnimTurn, args = {leaks, "Left"}})
+ table.insert(startAnim, {func = AnimSay, args = {leaks, loc("I wonder where Dense Cloud is..."), SAY_THINK, 4000}})
+ table.insert(startAnim, {func = AnimSay, args = {leaks, loc("He must be in the village already."), SAY_THINK, 4000}})
+ table.insert(startAnim, {func = AnimSay, args = {leaks, loc("I'd better get going myself."), SAY_THINK, 4000}})
+
+ midAnim = {}
+ table.insert(midAnim, {func = AnimWait, args = {leaks, 500}})
+ table.insert(midAnim, {func = AnimCustomFunction, swh = false, args = {leaks, RestoreCyborg, {1300, 1200, 1390, 1200}}})
+ table.insert(midAnim, {func = AnimSwitchHog, args = {cyborg}})
+ table.insert(midAnim, {func = AnimCustomFunction, args = {cyborg, TargetPrincess, {}}})
+ table.insert(midAnim, {func = AnimSay, args = {cyborg, loc("Welcome, Leaks A Lot!"), SAY_SAY, 3000}})
+ table.insert(midAnim, {func = AnimSay, args = {cyborg, loc("I want to play a game..."), SAY_SAY, 3000}})
+ table.insert(midAnim, {func = AnimSay, args = {princess, loc("Help me, please!!!"), SAY_SHOUT, 3000}})
+ table.insert(midAnim, {func = AnimSay, args = {cyborg, loc("If you can get that crate fast enough, your beloved \"princess\" may go free."), SAY_SAY, 7000}})
+ table.insert(midAnim, {func = AnimSay, args = {cyborg, loc("However, if you fail to do so, she dies a most violent death! Muahahaha!"), SAY_SAY, 8000}})
+ table.insert(midAnim, {func = AnimSay, args = {cyborg, loc("Good luck...or else!"), SAY_SAY, 4000}})
+ table.insert(midAnim, {func = AnimTeleportGear, args = {leaks, 2656, 1842}})
+ table.insert(midAnim, {func = AnimCustomFunction, args = {cyborg, HideCyborg, {}}, swh = false})
+ table.insert(midAnim, {func = AnimSay, args = {leaks, loc("Hey! This is cheating!"), SAY_SHOUT, 4000}})
+ AddSkipFunction(midAnim, SkipMidAnimAlone, {})
+end
+
+function SetupAnimAcceptedDied()
+ table.insert(startAnimAD, {func = AnimWait, args = {leaks, 3000}})
+ table.insert(startAnimAD, {func = AnimTurn, args = {leaks, "Left"}})
+ table.insert(startAnimAD, {func = AnimSay, args = {leaks, loc("I need to get to the other side of this island, fast!"), SAY_THINK, 5000}})
+ table.insert(startAnimAD, {func = AnimSay, args = {leaks, loc("With Dense Cloud on the land of shadows, I'm the village's only hope..."), SAY_THINK, 7000}})
+
+ table.insert(midAnimAD, {func = AnimWait, args = {leaks, 500}})
+ table.insert(midAnimAD, {func = AnimCustomFunction, swh = false, args = {leaks, RestoreCyborg, {1300, 1200, 1390, 1200}}})
+ table.insert(midAnimAD, {func = AnimSwitchHog, args = {cyborg}})
+ table.insert(midAnimAD, {func = AnimCustomFunction, args = {cyborg, TargetPrincess, {}}})
+ table.insert(midAnimAD, {func = AnimSay, args = {cyborg, loc("Welcome, Leaks A Lot!"), SAY_SAY, 3000}})
+ table.insert(midAnimAD, {func = AnimSay, args = {cyborg, loc("I want to play a game..."), SAY_SAY, 3000}})
+ table.insert(midAnimAD, {func = AnimSay, args = {princess, loc("Help me, please!!!"), SAY_SHOUT, 3000}})
+ table.insert(midAnimAD, {func = AnimSay, args = {cyborg, loc("If you can get that crate fast enough, your beloved \"princess\" may go free."), SAY_SAY, 7000}})
+ table.insert(midAnimAD, {func = AnimSay, args = {cyborg, loc("However, if you fail to do so, she dies a most violent death, just like your friend! Muahahaha!"), SAY_SAY, 8000}})
+ table.insert(midAnimAD, {func = AnimSay, args = {cyborg, loc("Good luck...or else!"), SAY_SAY, 4000}})
+ table.insert(midAnimAD, {func = AnimTeleportGear, args = {leaks, 2656, 1842}})
+ table.insert(midAnimAD, {func = AnimCustomFunction, args = {cyborg, HideCyborg, {}}, swh = false})
+ table.insert(midAnimAD, {func = AnimSay, args = {leaks, loc("Hey! This is cheating!"), SAY_SHOUT, 4000}})
+ AddSkipFunction(midAnimAD, SkipMidAnimAlone, {})
+
+ table.insert(failAnimAD, {func = AnimCustomFunction, swh = false, args = {leaks, RestoreCyborg, {2299, 1687, 2294, 1841}}})
+ table.insert(failAnimAD, {func = AnimTeleportGear, args = {leaks, 2090, 1841}})
+ table.insert(failAnimAD, {func = AnimCustomFunction, swh = false, args = {cyborg, SetupKillRoom, {}}})
+ table.insert(failAnimAD, {func = AnimTurn, swh = false, args = {cyborg, "Left"}})
+ table.insert(failAnimAD, {func = AnimTurn, swh = false, args = {princess, "Left"}})
+ table.insert(failAnimAD, {func = AnimTurn, swh = false, args = {leaks, "Right"}})
+ table.insert(failAnimAD, {func = AnimWait, args = {cyborg, 1000}})
+ table.insert(failAnimAD, {func = AnimSay, args = {cyborg, loc("You have failed to complete your task, young one!"), SAY_SAY, 6000}})
+ table.insert(failAnimAD, {func = AnimSay, args = {cyborg, loc("It's time you learned that your actions have consequences!"), SAY_SAY, 7000}})
+ table.insert(failAnimAD, {func = AnimSay, args = {princess, loc("No! Please, help me!"), SAY_SAY, 4000}})
+ table.insert(failAnimAD, {func = AnimSwitchHog, args = {cyborg}})
+ table.insert(failAnimAD, {func = AnimCustomFunction, args = {cyborg, DumpMines, {}}})
+ table.insert(failAnimAD, {func = AnimCustomFunction, args = {cyborg, KillPrincess, {}}})
+ table.insert(failAnimAD, {func = AnimWait, args = {cyborg, 12000}})
+ table.insert(failAnimAD, {func = AnimSay, args = {leaks, loc("No! What have I done?! What have YOU done?!"), SAY_SHOUT, 6000}})
+
+ table.insert(endAnimAD, {func = AnimCustomFunction, swh = false, args = {leaks, RestoreCyborg, {437, 1700, 519, 1722}}})
+ table.insert(endAnimAD, {func = AnimTurn, swh = false, args = {cyborg, "Right"}})
+ table.insert(endAnimAD, {func = AnimTurn, swh = false, args = {princess, "Right"}})
+ table.insert(endAnimAD, {func = AnimSay, args = {princess, loc("Help me, Leaks!"), SAY_SHOUT, 3000}})
+ table.insert(endAnimAD, {func = AnimSay, args = {leaks, loc("But you said you'd let her go!"), SAY_SHOUT, 5000}})
+ table.insert(endAnimAD, {func = AnimSay, args = {cyborg, loc("And you believed me? Oh, god, that's cute!"), SAY_SHOUT, 7000}})
+ table.insert(endAnimAD, {func = AnimSay, args = {leaks, loc("I won't let you kill her!"), SAY_SHOUT, 4000}})
+ AddSkipFunction(endAnimAD, SkipEndAnimAlone, {})
+
+ table.insert(endFailAnim, {func = AnimCaption, args = {leaks, loc("Leaks A Lot, depressed for killing his loved one, failed to save the village..."), 3000}})
+
+ table.insert(winAnimAD, {func = AnimCustomFunction, args = {princess, CondNeedToTurn, {leaks, princess}}})
+ table.insert(winAnimAD, {func = AnimSay, args = {princess, loc("Thank you, oh, thank you, Leaks A Lot!"), SAY_SAY, 5000}})
+ table.insert(winAnimAD, {func = AnimSay, args = {princess, loc("How can I ever repay you for saving my life?"), SAY_SAY, 6000}})
+ table.insert(winAnimAD, {func = AnimSay, args = {leaks, loc("There's nothing more satisfying for me than seeing you share your beauty with the world every morning, my princess!"), SAY_SAY, 10000}})
+ table.insert(winAnimAD, {func = AnimSay, args = {leaks, loc("Let's go home!"), SAY_SAY, 3000}})
+ table.insert(winAnimAD, {func = AnimCaption, args = {leaks, loc("And so they discovered that cyborgs weren't invulnerable..."), 2000}})
+
+ startAnim = startAnimAD
+ midAnim = midAnimAD
+ failAnim = failAnimAD
+ endAnim = endAnimAD
+ endFailAnim = endFailAnimAD
+ winAnim = winAnimAD
+end
+
+function SetupAnimAcceptedLived()
+ table.insert(startAnimAL, {func = AnimWait, args = {leaks, 3000}})
+ table.insert(startAnimAL, {func = AnimCustomFunction, args = {dense, CondNeedToTurn, {leaks, dense}}})
+ table.insert(startAnimAL, {func = AnimSay, args = {leaks, loc("All right, we just need to get to the other side of the island!"), SAY_SAY, 8000}})
+ table.insert(startAnimAL, {func = AnimSay, args = {dense, loc("We have no time to waste..."), SAY_SAY, 4000}})
+ table.insert(startAnimAL, {func = AnimSwitchHog, args = {leaks}})
+ AddSkipFunction(startAnimAL, SkipStartAnim, {})
+
+ table.insert(pastFlowerAnimAL, {func = AnimCustomFunction, args = {dense, RestoreCyborgOnly, {unpack(startCyborgPosDuo)}}, swh = false})
+ table.insert(pastFlowerAnimAL, {func = AnimTurn, args = {cyborg, "Right"}})
+ table.insert(pastFlowerAnimAL, {func = AnimSay, args = {cyborg, loc("Well, well! Isn't that the cutest thing you've ever seen?"), SAY_SAY, 7000}})
+ table.insert(pastFlowerAnimAL, {func = AnimSay, args = {cyborg, loc("Two little hogs cooperating, getting past obstacles..."), SAY_SAY, 7000}})
+ table.insert(pastFlowerAnimAL, {func = AnimSay, args = {cyborg, loc("Let me test your skills a little, will you?"), SAY_SAY, 6000}})
+ table.insert(pastFlowerAnimAL, {func = AnimTeleportGear, args = {cyborg, 2456, 1842}})
+ table.insert(pastFlowerAnimAL, {func = AnimTeleportGear, args = {dense, 2656, 1842}})
+ table.insert(pastFlowerAnimAL, {func = AnimCustomFunction, args = {dense, CondNeedToTurn, {cyborg, dense}}})
+ table.insert(pastFlowerAnimAL, {func = AnimSay, args = {dense, loc("Why are you doing this?"), SAY_SAY, 4000}})
+ table.insert(pastFlowerAnimAL, {func = AnimSay, args = {cyborg, loc("To help you, of course!"), SAY_SAY, 4000}})
+ table.insert(pastFlowerAnimAL, {func = AnimSwitchHog, args = {dense}})
+ table.insert(pastFlowerAnimAL, {func = AnimDisappear, swh = false, args = {cyborg, 3781, 1583}})
+ table.insert(pastFlowerAnimAL, {func = AnimCustomFunction, swh = false, args = {cyborg, HideCyborgOnly, {}}})
+ AddSkipFunction(pastFlowerAnimAL, SkipPastFlowerAnim, {})
+
+ table.insert(outPitAnimAL, {func = AnimCustomFunction, args = {dense, RestoreCyborgOnly, {unpack(midCyborgPosDuo)}}, swh = false})
+ table.insert(outPitAnimAL, {func = AnimTurn, args = {cyborg, "Right"}})
+ table.insert(outPitAnimAL, {func = AnimTeleportGear, args = {dense, unpack(midDensePosDuo)}})
+ table.insert(outPitAnimAL, {func = AnimTurn, args = {dense, "Left"}})
+ table.insert(outPitAnimAL, {func = AnimSay, args = {dense, loc("OH, COME ON!"), SAY_SHOUT, 3000}})
+ table.insert(outPitAnimAL, {func = AnimSay, args = {cyborg, loc("Let's see what your comrade does now!"), SAY_SAY, 5000}})
+ table.insert(outPitAnimAL, {func = AnimSwitchHog, args = {dense}})
+ table.insert(outPitAnimAL, {func = AnimDisappear, swh = false, args = {cyborg, 3781, 1583}})
+ table.insert(outPitAnimAL, {func = AnimCustomFunction, swh = false, args = {cyborg, HideCyborgOnly, {}}})
+ AddSkipFunction(outPitAnimAL, SkipOutPitAnim, {})
+
+ table.insert(endAnim, {func = AnimCustomFunction, swh = false, args = {leaks, RestoreCyborg, {437, 1700, 519, 1722}}})
+ table.insert(endAnim, {func = AnimTeleportGear, args = {leaks, 763, 1760}})
+ table.insert(endAnim, {func = AnimTeleportGear, args = {dense, 835, 1519}})
+ table.insert(endAnim, {func = AnimTurn, swh = false, args = {leaks, "Left"}})
+ table.insert(endAnim, {func = AnimTurn, swh = false, args = {dense, "Left"}})
+ table.insert(endAnim, {func = AnimTurn, swh = false, args = {cyborg, "Right"}})
+ table.insert(endAnim, {func = AnimTurn, swh = false, args = {princess, "Right"}})
+ table.insert(endAnim, {func = AnimSay, args = {princess, loc("Help me, please!"), SAY_SHOUT, 3000}})
+ table.insert(endAnim, {func = AnimSay, args = {leaks, loc("What are you doing? Let her go!"), SAY_SHOUT, 5000}})
+ table.insert(endAnim, {func = AnimSay, args = {cyborg, loc("Yeah? Watcha gonna do? Cry?"), SAY_SHOUT, 5000}})
+ table.insert(endAnim, {func = AnimSay, args = {leaks, loc("We won't let you hurt her!"), SAY_SHOUT, 4000}})
+ AddSkipFunction(endAnim, SkipEndAnimDuo, {})
+
+ table.insert(endFailAnim, {func = AnimCaption, args = {leaks, loc("Leaks A Lot, depressed for killing his loved one, failed to save the village..."), 3000}})
+
+ table.insert(winAnim, {func = AnimCustomFunction, args = {princess, CondNeedToTurn, {leaks, princess}}})
+ table.insert(winAnim, {func = AnimSay, args = {princess, loc("Thank you, oh, thank you, my heroes!"), SAY_SAY, 5000}})
+ table.insert(winAnim, {func = AnimSay, args = {princess, loc("How can I ever repay you for saving my life?"), SAY_SAY, 6000}})
+ table.insert(winAnim, {func = AnimSay, args = {leaks, loc("There's nothing more satisfying to us than seeing you share your beauty..."), SAY_SAY, 7000}})
+ table.insert(winAnim, {func = AnimSay, args = {leaks, loc("... share your beauty with the world every morning, my princess!"), SAY_SAY, 7000}})
+ table.insert(winAnim, {func = AnimSay, args = {leaks, loc("Let's go home!"), SAY_SAY, 3000}})
+ table.insert(winAnim, {func = AnimCaption, args = {leaks, loc("And so they discovered that cyborgs weren't invulnerable..."), 2000}})
+
+ startAnim = startAnimAL
+ pastFlowerAnim = pastFlowerAnimAL
+ outPitAnim = outPitAnimAL
+end
+
+function SetupAnimRefusedLived()
+ table.insert(startAnimRL, {func = AnimWait, args = {leaks, 3000}})
+ table.insert(startAnimRL, {func = AnimCustomFunction, args = {dense, CondNeedToTurn, {leaks, dense}}})
+ table.insert(startAnimRL, {func = AnimSay, args = {leaks, loc("All right, we just need to get to the other side of the island!"), SAY_SAY, 7000}})
+ table.insert(startAnimRL, {func = AnimSay, args = {dense, loc("Dude, can you see Ramon and Spiky?"), SAY_SAY, 5000}})
+ table.insert(startAnimRL, {func = AnimSay, args = {leaks, loc("No...I wonder where they disappeared?!"), SAY_SAY, 5000}})
+ AddSkipFunction(startAnimRL, SkipStartAnim, {})
+
+ table.insert(pastFlowerAnimRL, {func = AnimCustomFunction, args = {dense, RestoreCyborgOnly, {unpack(startCyborgPosDuo)}}, swh = false})
+ table.insert(pastFlowerAnimRL, {func = AnimTurn, args = {cyborg, "Right"}})
+ table.insert(pastFlowerAnimRL, {func = AnimSay, args = {cyborg, loc("Well, well! Isn't that the cutest thing you've ever seen?"), SAY_SAY, 7000}})
+ table.insert(pastFlowerAnimRL, {func = AnimSay, args = {cyborg, loc("Two little hogs cooperating, getting past obstacles..."), SAY_SAY, 7000}})
+ table.insert(pastFlowerAnimRL, {func = AnimSay, args = {cyborg, loc("Let me test your skills a little, will you?"), SAY_SAY, 6000}})
+ table.insert(pastFlowerAnimRL, {func = AnimTeleportGear, args = {cyborg, 2456, 1842}})
+ table.insert(pastFlowerAnimRL, {func = AnimTeleportGear, args = {dense, 2656, 1842}})
+ table.insert(pastFlowerAnimRL, {func = AnimCustomFunction, args = {dense, CondNeedToTurn, {cyborg, dense}}})
+ table.insert(pastFlowerAnimRL, {func = AnimSay, args = {dense, loc("Why are you doing this?"), SAY_SAY, 4000}})
+ table.insert(pastFlowerAnimRL, {func = AnimSay, args = {cyborg, loc("You couldn't possibly believe that after refusing my offer I'd just let you go!"), SAY_SAY, 9000}})
+ table.insert(pastFlowerAnimRL, {func = AnimSay, args = {cyborg, loc("You're funny!"), SAY_SAY, 4000}})
+ table.insert(pastFlowerAnimRL, {func = AnimSwitchHog, args = {dense}})
+ table.insert(pastFlowerAnimRL, {func = AnimDisappear, swh = false, args = {cyborg, 3781, 1583}})
+ table.insert(pastFlowerAnimRL, {func = AnimCustomFunction, swh = false, args = {cyborg, HideCyborgOnly, {}}})
+ AddSkipFunction(pastFlowerAnimRL, SkipPastFlowerAnim, {})
+
+ table.insert(outPitAnimRL, {func = AnimCustomFunction, args = {dense, RestoreCyborgOnly, {unpack(midCyborgPosDuo)}}, swh = false})
+ table.insert(outPitAnimRL, {func = AnimTurn, args = {cyborg, "Right"}})
+ table.insert(outPitAnimRL, {func = AnimTeleportGear, args = {dense, unpack(midDensePosDuo)}})
+ table.insert(outPitAnimRL, {func = AnimTurn, args = {dense, "Left"}})
+ table.insert(outPitAnimRL, {func = AnimSay, args = {dense, loc("OH, COME ON!"), SAY_SHOUT, 3000}})
+ table.insert(outPitAnimRL, {func = AnimSay, args = {cyborg, loc("Let's see what your comrade does now!"), SAY_SAY, 5000}})
+ table.insert(outPitAnimRL, {func = AnimSwitchHog, args = {dense}})
+ table.insert(outPitAnimRL, {func = AnimDisappear, swh = false, args = {cyborg, 3781, 1583}})
+ table.insert(outPitAnimRL, {func = AnimCustomFunction, swh = false, args = {cyborg, HideCyborgOnly, {}}})
+ AddSkipFunction(outPitAnimRL, SkipOutPitAnim, {})
+
+ table.insert(endAnim, {func = AnimCustomFunction, args = {leaks, RestoreCyborg, {437, 1700, 519, 1722}}})
+ table.insert(endAnim, {func = AnimTeleportGear, args = {leaks, 763, 1760}})
+ table.insert(endAnim, {func = AnimTeleportGear, args = {dense, 835, 1519}})
+ table.insert(endAnim, {func = AnimTurn, swh = false, args = {leaks, "Left"}})
+ table.insert(endAnim, {func = AnimTurn, swh = false, args = {dense, "Left"}})
+ table.insert(endAnim, {func = AnimTurn, swh = false, args = {cyborg, "Right"}})
+ table.insert(endAnim, {func = AnimTurn, swh = false, args = {princess, "Right"}})
+ table.insert(endAnim, {func = AnimSay, args = {princess, loc("Help me, please!"), SAY_SHOUT, 3000}})
+ table.insert(endAnim, {func = AnimSay, args = {leaks, loc("What are you doing? Let her go!"), SAY_SHOUT, 5000}})
+ table.insert(endAnim, {func = AnimSay, args = {cyborg, loc("Yeah? Watcha gonna do? Cry?"), SAY_SHOUT, 5000}})
+ table.insert(endAnim, {func = AnimSay, args = {leaks, loc("We won't let you hurt her!"), SAY_SHOUT, 4000}})
+ AddSkipFunction(endAnim, SkipEndAnimDuo, {})
+
+ table.insert(endFailAnim, {func = AnimCaption, args = {leaks, loc("Leaks A Lot, depressed for killing his loved one, failed to save the village..."), 3000}})
+
+ table.insert(winAnim, {func = AnimCustomFunction, args = {princess, CondNeedToTurn, {leaks, princess}}})
+ table.insert(winAnim, {func = AnimSay, args = {princess, loc("Thank you, oh, thank you, my heroes!"), SAY_SAY, 5000}})
+ table.insert(winAnim, {func = AnimSay, args = {princess, loc("How can I ever repay you for saving my life?"), SAY_SAY, 6000}})
+ table.insert(winAnim, {func = AnimSay, args = {leaks, loc("There's nothing more satisfying to us than seeing you share your beauty with the world every morning, my princess!"), SAY_SAY, 10000}})
+ table.insert(winAnim, {func = AnimSay, args = {leaks, loc("Let's go home!"), SAY_SAY, 3000}})
+ table.insert(winAnim, {func = AnimCaption, args = {leaks, loc("And so they discovered that cyborgs weren't invulnerable..."), 2000}})
+
+ startAnim = startAnimRL
+ pastFlowerAnim = pastFlowerAnimRL
+ outPitAnim = outPitAnimRL
+end
+
+function KillPrincess()
+ ParseCommand("teamgone " .. loc("Cannibal Sentry"))
+ TurnTimeLeft = 0
+end
+--/////////////////////////////Misc Functions////////////////////////
+
+function HideHedge(hedge)
+ if hedgeHidden[hedge] ~= true then
+ HideHog(hedge)
+ hedgeHidden[hedge] = true
+ end
+end
+
+function RestoreHedge(hedge)
+ if hedgeHidden[hedge] == true then
+ RestoreHog(hedge)
+ hedgeHidden[hedge] = false
+ end
+end
+
+function CondNeedToTurn(hog1, hog2)
+ xl, xd = GetX(hog1), GetX(hog2)
+ if xl > xd then
+ AnimInsertStepNext({func = AnimTurn, args = {hog1, "Left"}})
+ AnimInsertStepNext({func = AnimTurn, args = {hog2, "Right"}})
+ elseif xl < xd then
+ AnimInsertStepNext({func = AnimTurn, args = {hog2, "Left"}})
+ AnimInsertStepNext({func = AnimTurn, args = {hog1, "Right"}})
+ end
+end
+
+function SetupPlaceAlone()
+ ------ AMMO CRATE LIST ------
+ --SpawnAmmoCrate(3122, 994, amShotgun)
+ SpawnAmmoCrate(3124, 952, amBaseballBat)
+ SpawnAmmoCrate(2508, 1110, amFirePunch)
+ ------ UTILITY CRATE LIST ------
+ blowCrate = SpawnUtilityCrate(3675, 1480, amBlowTorch)
+ gravityCrate = SpawnUtilityCrate(3448, 1349, amLowGravity)
+ SpawnUtilityCrate(3212, 1256, amGirder)
+ SpawnUtilityCrate(3113, 911, amParachute)
+ sniperCrate = SpawnAmmoCrate(784, 1715, amSniperRifle)
+ ------ MINE LIST ------
+ SetTimer(AddGear(3328, 1399, gtMine, 0, 0, 0, 0), 3000)
+ SetTimer(AddGear(3028, 1262, gtMine, 0, 0, 0, 0), 3000)
+ SetTimer(AddGear(2994, 1274, gtMine, 0, 0, 0, 0), 3000)
+ SetTimer(AddGear(2956, 1277, gtMine, 0, 0, 0, 0), 3000)
+ SetTimer(AddGear(2925, 1282, gtMine, 0, 0, 0, 0), 3000)
+ SetTimer(AddGear(2838, 1276, gtMine, 0, 0, 0, 0), 3000)
+ SetTimer(AddGear(2822, 1278, gtMine, 0, 0, 0, 0), 3000)
+ SetTimer(AddGear(2786, 1283, gtMine, 0, 0, 0, 0), 3000)
+ SetTimer(AddGear(2766, 1270, gtMine, 0, 0, 0, 0), 3000)
+ SetTimer(AddGear(2749, 1231, gtMine, 0, 0, 0, 0), 3000)
+ SetTimer(AddGear(2717, 1354, gtMine, 0, 0, 0, 0), 3000)
+ SetTimer(AddGear(2167, 1330, gtMine, 0, 0, 0, 0), 3000)
+ SetTimer(AddGear(2201, 1321, gtMine, 0, 0, 0, 0), 3000)
+ SetTimer(AddGear(2239, 1295, gtMine, 0, 0, 0, 0), 3000)
+
+ AnimSetGearPosition(leaks, 3781, 1583)
+ --AnimSetGearPosition(leaks, 1650, 1583)
+ AddAmmo(cannibals[1], amShotgun, 100)
+ AddAmmo(leaks, amSwitch, 0)
+end
+
+function SetupPlaceDuo()
+ PlaceCratesDuo()
+ AnimSetGearPosition(leaks, unpack(startLeaksPosDuo))
+ AnimSetGearPosition(dense, unpack(startDensePosDuo))
+end
+
+function SetupEventsDuo()
+ AddEvent(CheckPastFlower, {}, DoPastFlower, {}, 0)
+ AddEvent(CheckLeaksDead, {}, DoLeaksDead, {}, 0)
+ AddEvent(CheckDenseDead, {}, DoDenseDead, {}, 0)
+ AddEvent(CheckTookSniper2, {}, DoTookSniper2, {}, 0)
+end
+
+function SetupEventsAlone()
+ AddEvent(CheckLeaksDead, {}, DoLeaksDead, {}, 0)
+ AddEvent(CheckTookBlowTorch, {}, DoTookBlowTorch, {}, 0)
+ AddEvent(CheckTookLowGravity, {}, DoTookLowGravity, {}, 0)
+ AddEvent(CheckOnBridge, {}, DoOnBridge, {}, 0)
+end
+
+function StartMission()
+ if m2DenseDead == 1 then
+ DeleteGear(dense)
+ if m2Choice == choiceAccepted then
+ SetupAnimAcceptedDied()
+ elseif m2Choice == choiceRefused then
+ SetupAnimRefusedDied()
+ else
+ SetupAnimAttacked()
+ end
+ SetupPlaceAlone()
+ SetupEventsAlone()
+ AddAnim(startAnim)
+ AddFunction({func = AfterStartAnim, args = {}})
+ else
+ if m2Choice == choiceAccepted then
+ SetupAnimAcceptedLived()
+ else
+ SetupAnimRefusedLived()
+ end
+ SetupPlaceDuo()
+ SetupEventsDuo()
+ AddAnim(startAnim)
+ AddFunction({func = AfterStartAnim, args = {}})
+ end
+ HideHedge(cyborg)
+ HideHedge(princess)
+ for i = 5, 8 do
+ HideHedge(cannibals[i])
+ end
+
+end
+
+function SetupCourse()
+
+ ------ GIRDER LIST ------
+ PlaceGirder(1091, 1150, 6)
+ PlaceGirder(1091, 989, 6)
+ PlaceGirder(1091, 829, 6)
+ PlaceGirder(1091, 669, 6)
+ PlaceGirder(1091, 668, 6)
+ PlaceGirder(1091, 669, 6)
+ PlaceGirder(1088, 667, 6)
+ PlaceGirder(1091, 658, 6)
+ PlaceGirder(1091, 646, 6)
+ PlaceGirder(1091, 607, 6)
+ PlaceGirder(1091, 571, 6)
+ PlaceGirder(1376, 821, 6)
+ PlaceGirder(1145, 1192, 1)
+ PlaceGirder(1169, 1076, 3)
+ PlaceGirder(1351, 1082, 4)
+ PlaceGirder(1469, 987, 3)
+ PlaceGirder(1386, 951, 0)
+ PlaceGirder(1465, 852, 3)
+ PlaceGirder(1630, 913, 0)
+ PlaceGirder(1733, 856, 7)
+ PlaceGirder(1688, 713, 5)
+ PlaceGirder(1556, 696, 2)
+ PlaceGirder(1525, 696, 2)
+ PlaceGirder(1457, 697, 2)
+ PlaceGirder(1413, 700, 3)
+ PlaceGirder(1270, 783, 2)
+ PlaceGirder(1207, 825, 2)
+ PlaceGirder(1135, 775, 1)
+
+ ------ UTILITY CRATE LIST ------
+ SpawnUtilityCrate(1590, 628, amParachute)
+ SpawnAmmoCrate(1540, 100, amDynamite)
+ SpawnUtilityCrate(2175, 1815, amLowGravity)
+ SpawnUtilityCrate(2210, 1499, amFirePunch)
+ girderCrate = SpawnUtilityCrate(2300, 1663, amGirder)
+ SpawnUtilityCrate(610, 1394, amPickHammer)
+
+ ------ BARREL LIST ------
+ SetHealth(AddGear(1148, 736, gtExplosives, 0, 0, 0, 0), 20)
+
+end
+
+function PlaceCourseMines()
+ SetTimer(AddGear(1215, 1193, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(1259, 1199, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(1310, 1198, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(1346, 1196, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(1383, 1192, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(1436, 1196, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(1487, 1199, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(1651, 1209, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(1708, 1209, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(1759, 1190, gtMine, 0, 0, 0, 0), 5000)
+ SetTimer(AddGear(1815, 1184, gtMine, 0, 0, 0, 0), 5000)
+end
+
+
+--////////////////////////////Event Functions////////////////////////
+function CheckTookFire()
+ return fireTaken
+end
+
+function DoTookFire()
+ AddAmmo(leaks, amFirePunch, 100)
+end
+
+function CheckTookGirder1()
+ return girder1Taken
+end
+
+function CheckTookGirder2()
+ return girder2Taken
+end
+
+function DoTookGirder1()
+ AddAmmo(dense, amGirder, 2)
+end
+
+function DoTookGirder2()
+ AddAmmo(dense, amGirder, 3)
+end
+
+function CheckDensePit()
+ return GetY(dense) < 1250 and StoppedGear(dense)
+end
+
+function DoDensePit()
+ TurnTimeLeft = 0
+ RestoreHedge(cyborg)
+ AnimWait(cyborg, 1)
+ AddFunction({func = AddAnim, args = {outPitAnim}})
+ AddFunction({func = AddFunction, args = {{func = AfterOutPitAnim, args = {}}}})
+end
+
+function CheckPastFlower()
+ if denseDead == true or leaksDead == true then
+ return false
+ end
+ return (GetX(dense) < startEventXDuo and StoppedGear(dense))
+ or (GetX(leaks) < startEventXDuo and StoppedGear(leaks))
+end
+
+function DoPastFlower()
+ TurnTimeLeft = 0
+ RestoreHedge(cyborg)
+ AnimWait(cyborg, 1)
+ AddFunction({func = AddAnim, args = {pastFlowerAnim}})
+ AddFunction({func = AddFunction, args = {{func = AfterPastFlowerAnim, args = {}}}})
+end
+
+
+function CheckLeaksDead()
+ return leaksDead
+end
+
+function DoLeaksDead()
+ AddCaption(loc("The village, unprepared, was destroyed by the cyborgs..."))
+ ParseCommand("teamgone " .. loc("Natives"))
+end
+
+function CheckDenseDead()
+ return denseDead
+end
+
+function DoDenseDead()
+ AddCaption(loc("The village, unprepared, was destroyed by the cyborgs..."))
+ ParseCommand("teamgone " .. loc("Natives"))
+end
+
+function CheckTookBlowTorch()
+ return blowTaken
+end
+
+function DoTookBlowTorch()
+ ShowMission(loc("The Journey Back"), loc("The Tunnel Maker"), loc("Hint: Select the BlowTorch, aim and press [Fire]. Press [Fire] again to stop.|Don't blow up the crate."), 0, 6000)
+end
+
+function CheckTookLowGravity()
+ return gravityTaken
+end
+
+function DoTookLowGravity()
+ ShowMission(loc("The Journey Back"), loc("The Moonwalk"), loc("Hint: Select the LowGravity and press [Fire]."), 0, 6000)
+end
+
+function CheckOnBridge()
+ return leaksDead == false and GetX(leaks) < 1651 and StoppedGear(leaks)
+end
+
+function DoOnBridge()
+ TurnTimeLeft = 0
+ RestoreHedge(cyborg)
+ RestoreHedge(princess)
+ AnimWait(cyborg, 1)
+ AddFunction({func = AddAnim, args = {midAnim}})
+ AddFunction({func = AddFunction, args = {{func = AfterMidAnimAlone, args = {}}}})
+end
+
+function CheckGirderTaken()
+ return girderTaken
+end
+
+function DoGirderTaken()
+ AddAmmo(leaks, amGirder, 2)
+-- AddAmmo(leaks, amGirder, 3)
+end
+
+function CheckOnFirstGirder()
+ return leaksDead == false and GetX(leaks) < 1160 and StoppedGear(leaks)
+end
+
+function DoOnFirstGirder()
+ PlaceCourseMines()
+ ShowMission(loc("The Journey Back"), loc("Slippery"), loc("You'd better watch your steps..."), 0, 4000)
+end
+
+function CheckTookSniper()
+ return sniperTaken and StoppedGear(leaks)
+end
+
+function DoTookSniper()
+ TurnTimeLeft = 0
+ RestoreHedge(cyborg)
+ RestoreHedge(princess)
+ AnimWait(cyborg, 1)
+ AddFunction({func = AddAnim, args = {endAnim}})
+ AddFunction({func = AddFunction, args = {{func = AfterEndAnimAlone, args = {}}}})
+end
+
+function CheckTookSniper2()
+ return sniperTaken and StoppedGear(leaks) and StoppedGear(dense)
+end
+
+function DoTookSniper2()
+ TurnTimeLeft = 0
+ RestoreHedge(cyborg)
+ RestoreHedge(princess)
+ AnimWait(cyborg, 1)
+ AddFunction({func = AddAnim, args = {endAnim}})
+ AddFunction({func = AddFunction, args = {{func = AfterEndAnimDuo, args = {}}}})
+end
+
+function CheckLost()
+ return princessDead
+end
+
+function DoLost()
+ AddAnim(endFailAnim)
+ AddFunction({func = ParseCommand, args = {'teamgone ' .. loc('Natives')}})
+end
+
+function CheckWon()
+ return cyborgDead and not princessDead
+end
+
+function DoWon()
+ if progress and progress<3 then
+ SaveCampaignVar("Progress", "3")
+ end
+ AddAnim(winAnim)
+ AddFunction({func = FinishWon, args = {}})
+end
+
+function FinishWon()
+ SwitchHog(leaks)
+ ParseCommand("teamgone " .. loc("Cannibal Sentry"))
+ ParseCommand("teamgone " .. loc("011101001"))
+ TurnTimeLeft = 0
+end
+
+function CheckFailedCourse()
+ return TurnsLeft == 0
+end
+
+function DoFailedCourse()
+ TurnTimeLeft = 0
+ RestoreHedge(cyborg)
+ RestoreHedge(princess)
+ AnimWait(cyborg, 1)
+ AddFunction({func = AddAnim, args = {failAnim}})
+ AddFunction({func = AddFunction, args = {{func = AfterMidFailAnim, args = {}}}})
+end
+
+--////////////////////////////Main Functions/////////////////////////
+
+function onGameInit()
+ Seed = 0
+ GameFlags = gfSolidLand + gfDisableWind
+ TurnTime = 40000
+ CaseFreq = 0
+ MinesNum = 0
+ MinesTime = 3000
+ Explosives = 0
+ Delay = 5
+ Map = "A_Classic_Fairytale_journey"
+ Theme = "Nature"
+
+ SuddenDeathTurns = 3000
+
+ AddTeam(loc("Natives"), 29439, "Bone", "Island", "HillBilly", "cm_birdy")
+ leaks = AddHog(loc("Leaks A Lot"), 0, 100, "Rambo")
+ dense = AddHog(loc("Dense Cloud"), 0, 100, "RobinHood")
+
+ AddTeam(loc("Cannibal Sentry"), 14483456, "Skull", "Island", "Pirate","cm_vampire")
+ cannibals = {}
+ for i = 1, 4 do
+ cannibals[i] = AddHog(cannibalNames[i], 3, 40, "Zombi")
+ AnimSetGearPosition(cannibals[i], unpack(cannibalPos[i]))
+ end
+
+ for i = 5, 8 do
+ cannibals[i] = AddHog(cannibalNames[i], 3, 40, "Zombi")
+ AnimSetGearPosition(cannibals[i], 0, 0)
+ end
+
+ AddTeam(loc("011101001"), 14483456, "ring", "UFO", "Robot", "cm_star")
+ cyborg = AddHog(loc("Y3K1337"), 0, 200, "cyborg1")
+ princess = AddHog(loc("Fell From Heaven"), 0, 200, "tiara")
+
+ AnimSetGearPosition(dense, 0, 0)
+ AnimSetGearPosition(leaks, 0, 0)
+ AnimSetGearPosition(cyborg, 0, 0)
+ AnimSetGearPosition(princess, 0, 0)
+
+ AnimInit()
+end
+
+function onGameStart()
+ progress = tonumber(GetCampaignVar("Progress"))
+ m2Choice = tonumber(GetCampaignVar("M2Choice"))
+ m2DenseDead = tonumber(GetCampaignVar("M2DenseDead"))
+ m2RamonDead = tonumber(GetCampaignVar("M2RamonDead"))
+ m2SpikyDead = tonumber(GetCampaignVar("M2SpikyDead"))
+ StartMission()
+end
+
+function onGameTick()
+ AnimUnWait()
+ if ShowAnimation() == false then
+ return
+ end
+ ExecuteAfterAnimations()
+ CheckEvents()
+end
+
+function onGearDelete(gear)
+ if gear == blowCrate then
+ blowTaken = true
+ elseif gear == fireCrate then
+ fireTaken = true
+ elseif gear == gravityCrate then
+ gravityTaken = true
+ elseif gear == leaks then
+ leaksDead = true
+ elseif gear == dense then
+ denseDead = true
+ elseif gear == cyborg then
+ cyborgDead = true
+ elseif gear == princess then
+ princessDead = true
+ elseif gear == girderCrate then
+ girderTaken = true
+ elseif gear == girderCrate1 then
+ girder1Taken = true
+ elseif gear == girderCrate2 then
+ girder2Taken = true
+ elseif gear == sniperCrate then
+ sniperTaken = true
+ else
+ for i = 1, 4 do
+ if gear == cannibals[i] then
+ cannibalDead[i] = true
+ end
+ end
+ end
+end
+
+function onAmmoStoreInit()
+ SetAmmo(amBlowTorch, 0, 0, 0, 1)
+ SetAmmo(amParachute, 0, 0, 0, 1)
+ SetAmmo(amGirder, 0, 0, 0, 3)
+ SetAmmo(amLowGravity, 0, 0, 0, 1)
+ SetAmmo(amBaseballBat, 0, 0, 0, 1)
+ SetAmmo(amFirePunch, 1, 0, 0, 1)
+ SetAmmo(amSkip, 9, 0, 0, 0)
+ SetAmmo(amSwitch, 9, 0, 0, 0)
+ SetAmmo(amDEagle, 9, 0, 0, 0)
+ SetAmmo(amRope, 0, 0, 0, 1)
+ SetAmmo(amSniperRifle, 0, 0, 0, 1)
+ SetAmmo(amDynamite, 0, 0, 0, 1)
+ SetAmmo(amPickHammer, 0, 0, 0, 1)
+end
+
+function onNewTurn()
+ if AnimInProgress() then
+ TurnTimeLeft = -1
+ elseif stage == endStage and CurrentHedgehog ~= leaks then
+ AnimSwitchHog(leaks)
+ SetGearMessage(leaks, 0)
+ TurnTimeLeft = -1
+ elseif GetHogTeamName(CurrentHedgehog) ~= loc("Natives") then
+ for i = 1, 4 do
+ if cannibalDead[i] ~= true then
+ if GetX(cannibals[i]) < GetX(leaks) then
+ HogTurnLeft(cannibals[i], false)
+ else
+ HogTurnLeft(cannibals[i], true)
+ end
+ end
+ end
+ SetInputMask(band(0xFFFFFFFF, bnot(gmLeft + gmRight + gmLJump + gmHJump)))
+ TurnTimeLeft = 20000
+ else
+ SetInputMask(0xFFFFFFFF)
+ TurnsLeft = TurnsLeft - 1
+ end
+end
+
+function onPrecise()
+ if GameTime > 2500 and AnimInProgress() then
+ SetAnimSkip(true)
+ return
+ end
+-- AddAmmo(leaks, amRope, 100)
+-- RemoveEventFunc(CheckPastFlower)
+-- DeleteGear(sniperCrate)
+end
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Missions/Campaign/A_Classic_Fairytale/queen.lua Mon Jul 01 23:23:22 2013 +0300
@@ -0,0 +1,828 @@
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Animate.lua")
+
+
+-----------------------------Map--------------------------------------
+local map =
+{
+ "\16\7\0\225\132\15\200\1\40\0\15\200\1\40\132\15\105\8\81\0\16\14\1\64\143\15\200\7\249\0\13\50\7\252\132\12\243\7\172\0",
+ "\12\236\7\168\132\12\127\6\192\0\12\127\6\192\132\11\52\6\223\0\11\52\6\223\132\10\62\8\35\0\8\201\8\4\132\8\63\7\126\0",
+ "\8\63\7\126\132\8\4\6\58\0\8\0\6\65\132\7\147\6\241\0\7\133\6\195\132\7\20\4\151\0\7\143\6\195\132\7\140\6\234\0",
+ "\7\17\4\151\132\5\191\4\222\0\5\191\4\222\132\3\136\3\252\0\3\136\3\252\132\2\12\4\151\0\2\12\4\151\132\1\138\5\15\0",
+ "\1\138\5\15\132\1\54\5\156\0\1\54\5\156\132\0\130\5\64\0\0\130\5\64\132\255\214\5\135\0\8\141\1\85\179\8\141\1\85\0",
+ "\10\30\2\220\139\10\30\2\220\0\11\77\1\142\131\11\77\1\142\0\10\188\0\113\129\10\188\0\113\0\255\235\0\162\132\0\130\0\225\0",
+ "\0\130\0\229\0\0\127\0\236\132\255\231\0\250\0\0\28\0\215\136\0\4\0\211\0\0\95\5\212\154\0\95\7\238\0\0\246\6\2\154",
+ "\1\71\8\0\0\1\205\5\145\154\2\132\4\239\0\3\98\4\141\154\1\135\5\216\0\3\179\4\151\154\6\213\5\247\0\6\223\5\124\151",
+ "\6\185\5\22\0\6\181\5\29\151\6\37\5\64\0\0\179\5\198\148\0\179\5\198\0\6\216\4\253\148\6\216\4\253\0\1\230\7\147\153",
+ "\8\32\8\18\0\1\187\6\174\153\7\179\7\108\0\2\199\5\177\179\6\128\6\167\0\7\231\7\10\143\7\231\6\202\0\12\148\8\4\156",
+ "\10\241\8\11\0\11\112\7\101\156\12\56\7\91\0\1\89\5\223\199\4\11\5\208\0\4\67\5\212\200\4\172\6\58\0\4\172\6\58\200",
+ "\5\36\5\212\0\5\40\5\194\200\4\169\5\57\0\4\169\5\57\200\4\42\5\205\0\4\130\5\142\200\4\218\5\205\0\4\137\5\194\200",
+ "\4\179\5\251\0\255\245\1\198\133\0\77\1\198\0\0\77\1\198\133\0\102\1\226\0\0\102\1\230\133\255\221\1\244\0\255\245\0\148\195",
+ "\255\231\1\11\0\0\32\0\162\195\255\231\0\169\0\0\60\0\158\195\0\32\0\172\0\0\21\0\176\195\255\242\0\222\0\255\245\0\215\195",
+ "\0\7\0\246\0\255\245\0\243\195\0\11\1\33\0\0\4\1\4\195\0\56\1\36\0\255\245\1\173\195\0\35\1\110\0\255\242\1\180\195",
+ "\255\224\2\9\0\255\238\1\240\195\0\28\2\30\0\0\21\2\19\195\0\102\2\23\0\16\18\1\1\195\16\35\0\222\0\16\14\1\11\195",
+ "\16\7\2\9\0\16\0\2\16\195\16\35\3\34\0\16\11\2\252\195\16\11\4\208\0\16\11\4\208\195\16\0\6\55\0\16\0\6\55\195",
+ "\16\14\8\25\0",
+}
+
+--------------------------------------------Constants------------------------------------
+choiceAccepted = 1
+choiceRefused = 2
+choiceAttacked = 3
+
+choiceEliminate = 1
+choiceSpare = 2
+
+leaksNum = 1
+denseNum = 2
+waterNum = 3
+buffaloNum = 4
+chiefNum = 5
+girlNum = 6
+wiseNum = 7
+
+denseScene = 1
+princessScene = 2
+waterScene = 3
+cyborgScene = 4
+
+nativeNames = {loc("Leaks A Lot"), loc("Dense Cloud"), loc("Fiery Water"),
+ loc("Raging Buffalo"), loc("Righteous Beard"), loc("Fell From Grace"),
+ loc("Wise Oak"), loc("Ramon"), loc("Spiky Cheese")
+ }
+nativeSaveNames = {"M8DeployedDead", "M8RamonDead", "M8SpikyDead", "M8PrincessDead"}
+
+nativeUnNames = {loc("Zork"), loc("Steve"), loc("Jack"),
+ loc("Lee"), loc("Elmo"), loc("Rachel"),
+ loc("Muriel")}
+
+nativeHats = {"Rambo", "RobinHood", "pirate_jack", "zoo_Bunny", "IndianChief",
+ "tiara", "AkuAku", "rasta", "hair_yellow"}
+
+nativePos = {{1474, 1188}, {923, 986}, {564, 1120}, {128, 1315}}
+nativesNum = 4
+nativesLeft = 4
+
+cyborgNames = {loc("Artur Detour"), loc("Led Heart"), loc("Orlando Boom!"), loc("Nilarian"),
+ loc("Steel Eye"), loc("Rusty Joe"), loc("Hatless Jerry"), loc("Gas Gargler")}
+
+cyborgsDif = {2, 2, 2, 2, 2, 2, 2, 2}
+cyborgsHealth = {100, 100, 100, 100, 100, 100, 100, 100}
+cyborgPos = {1765, 1145}
+cyborgsTeamNum = {4, 3}
+cyborgsNum = 7
+cyborgsPos = {{2893, 1717}, {2958, 1701}, {3027, 1696}, {3096, 1698},
+ {2584, 655}, {2047, 1534}, {115, 179}, {2162, 1916}}
+cyborgsDir = {"Left", "Left", "Left", "Left", "Left", "Left", "Right", "Left"}
+
+crateConsts = {}
+reactions = {}
+
+enemyPos = {4078, 195}
+
+-----------------------------Variables---------------------------------
+natives = {}
+origNatives = {}
+
+cyborgs = {}
+cyborg = nil
+
+gearDead = {}
+hedgeHidden = {}
+
+scene = 0
+enemyFled = "0"
+
+deployedLeader = "0"
+princessLeader = "0"
+
+startAnim = {}
+fleeAnim = {}
+finalAnim = {}
+leaderDeadAnim = {}
+-----------------------------Animations--------------------------------
+function EmitDenseClouds(dir)
+ local dif
+ if dir == "Left" then
+ dif = 10
+ else
+ dif = -10
+ end
+ if dir == nil then
+ dx, dy = GetGearVelocity(dense)
+ if dx < 0 then
+ dif = 10
+ else
+ dif = -10
+ end
+ end
+ AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
+ AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
+ AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
+ AnimInsertStepNext({func = AnimWait, args = {dense, 800}})
+ AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
+ AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
+ AnimInsertStepNext({func = AnimWait, args = {dense, 800}})
+ AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
+end
+
+function AnimationSetup()
+ table.insert(startAnim, {func = AnimWait, args = {enemy, 3000}})
+ table.insert(startAnim, {func = AnimCaption, swh = false, args = {natives[1], "The team continued their quest of finding the rest of the tribe.", 4000}})
+ table.insert(startAnim, {func = AnimCaption, swh = false, args = {natives[1], "They stumbled upon a pile of weapons, they seemed to be getting closer.", 4500}})
+ if scene == denseScene then
+ if m5DeployedNum == denseNum then
+ deployedLeader = "1"
+ SetupDenseAnimDeployed()
+ else
+ SetupDenseAnim()
+ end
+ elseif scene == waterScene then
+ if m5DeployedNum == waterNum then
+ deployedLeader = "1"
+ SetupWaterAnimDeployed()
+ else
+ SetupWaterAnim()
+ end
+ elseif scene == princessScene then
+ princessLeader = "1"
+ SetupPrincessAnim()
+ else
+ SetupCyborgAnim()
+ end
+
+ AddSkipFunction(startAnim, SkipAnim, {startAnim})
+ AddSkipFunction(fleeAnim, SkipAnim, {fleeAnim})
+ AddSkipFunction(leaderDeadAnim, SkipAnim, {leaderDeadAnim})
+end
+
+function SetupLeaderDeadAnim()
+ local gear = nil
+ if CheckCyborgsDead() then
+ return
+ end
+ for i = nativesLeft, 1, -1 do
+ if band(GetState(natives[i]), gstDrowning) == 0 then
+ gear = natives[i]
+ end
+ end
+ if gear == nil then
+ return
+ end
+ table.insert(leaderDeadAnim, {func = AnimFollowGear, args = {gear}})
+ table.insert(leaderDeadAnim, {func = AnimSay, args = {gear, "That traitor won't be killing us anymore!", SAY_THINK, 6000}})
+end
+
+function SetupDenseAnim()
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "Yo, dude! Get away from our weapons!", SAY_SHOUT, 5500}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "Dense Cloud?! What are you doing?!", SAY_SHOUT, 5500}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "What does it look like?", SAY_SHOUT, 3500}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "Are you helping the aliens?!", SAY_SHOUT, 4000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "Lolz, I love the look on your face!", SAY_SHOUT, 5000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "Did you really think that I'd changed?", SAY_SHOUT, 5500}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "But why did you betray us?!", SAY_SHOUT, 4000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "Yo, the aliens gave me plants...medicinal plants...lots of it.", SAY_SHOUT, 6500}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "You never give me plants!", SAY_SHOUT, 5500}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "Besides, why would I choose certain death?", SAY_SHOUT, 5500}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "Do you have any idea how bad an exploding arrow hurts?", SAY_SHOUT, 5500}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "Dude, it's unbearable!", SAY_SHOUT, 5500}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "You're a coward!", SAY_SHOUT, 3000}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "You endangered your whole tribe, you bastard!", SAY_SHOUT, 7000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "Yeah, well, for some dude to be happy, some other dude has to suffer.", SAY_SHOUT, 11000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "That's just the way it works, you know.", SAY_SHOUT, 6500}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "You're some piece of hypocrite junkie!", SAY_SHOUT, 6000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "Why do you always have to call me names?", SAY_SHOUT, 6000}})
+ table.insert(startAnim, {func = AnimCustomFunction, args = {enemy, EmitDenseClouds, {}}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "Make fun of me when I fart...", SAY_SHOUT, 5000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "IT'S A SERIOUS MEDICAL CONDITION!", SAY_SHOUT, 5000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "You don't deserve my sacrifice!", SAY_SHOUT, 5000}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "I won't let you kill the tribe!", SAY_SHOUT, 5000}})
+
+ table.insert(fleeAnim, {func = AnimSay, args = {enemy, "Dude, this is boring!", SAY_SAY, 3000}})
+ table.insert(fleeAnim, {func = AnimSay, args = {enemy, "I ain't gonna sit around no more!", SAY_SAY, 5000}})
+ table.insert(fleeAnim, {func = AnimTurn, args = {enemy, "Right"}})
+ table.insert(fleeAnim, {func = AnimSay, args = {enemy, "Yo, escort my buttocks!", SAY_SHOUT, 3500}})
+ table.insert(fleeAnim, {func = AnimSwitchHog, args = {natives[1]}})
+ table.insert(fleeAnim, {func = AnimWait, args = {natives[1], 1}})
+ table.insert(fleeAnim, {func = AnimDisappear, swh = false, args = {enemy, 0, 0}})
+end
+
+function SetupDenseAnimDeployed()
+ table.insert(startAnim, {func = AnimCustomFunction, args = {enemy, EmitDenseClouds, {}}})
+ table.insert(startAnim, {func = AnimCustomFunction, args = {enemy, CondNeedToTurn, {natives[3], enemy}}})
+ table.insert(startAnim, {func = AnimCustomFunction, args = {enemy, CondNeedToTurn, {natives[2], enemy}}})
+ table.insert(startAnim, {func = AnimCustomFunction, args = {enemy, CondNeedToTurn, {natives[1], enemy}}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "I'm afraid I can't let you proceed!", SAY_SHOUT, 5000}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "???", SAY_THINK, 0}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[2], "???", SAY_THINK, 0}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[3], "???", SAY_THINK, 1000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "Dude, wow, you're so cute!", SAY_SHOUT, 4000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "Did you really think I'd change?", SAY_SHOUT, 4500}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "I'm still with the aliens.", SAY_SHOUT, 4000}})
+ table.insert(startAnim, {func = AnimTeleportGear, args = {enemy, unpack(enemyPos)}})
+ table.insert(startAnim, {func = AnimCustomFunction, args = {enemy, CondNeedToTurn, {natives[1], enemy}}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "WHAT?!", SAY_THINK, 1000}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[3], "But you saved me!", SAY_THINK, 2500}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "Haha, that was just a coincidence!", SAY_SHOUT, 4000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "I was heading home, you see!", SAY_SHOUT, 3500}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "We were your home! Your family...", SAY_SHOUT, 4000}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "How could you betray us?!", SAY_SHOUT, 4000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "Yo, the aliens gave me plants...medicinal plants...lots of it.", SAY_SHOUT, 6500}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "You never give me plants!", SAY_SHOUT, 5500}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "Besides, why would I choose certain death?", SAY_SHOUT, 5500}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "Do you have any idea how bad an exploding arrow hurts?", SAY_SHOUT, 5500}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "Dude, it's unbearable!", SAY_SHOUT, 5500}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "You're a coward!", SAY_SHOUT, 3000}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "You endangered your whole tribe, you bastard!", SAY_SHOUT, 7000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "Yeah, well, for some dude to be happy, some other dude has to suffer.", SAY_SHOUT, 11000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "That's just the way it works, you know.", SAY_SHOUT, 6500}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "You're some piece of hypocrite junkie!", SAY_SHOUT, 6000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "Why do you always have to call me names?", SAY_SHOUT, 6000}})
+ table.insert(startAnim, {func = AnimCustomFunction, args = {enemy, EmitDenseClouds, {}}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "Make fun of me when I fart...", SAY_SHOUT, 5000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "IT'S A SERIOUS MEDICAL CONDITION!", SAY_SHOUT, 5000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "You don't deserve my sacrifice!", SAY_SHOUT, 5000}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "I won't let you kill the tribe!", SAY_SHOUT, 5000}})
+
+ table.insert(fleeAnim, {func = AnimSay, args = {enemy, "Dude, this is boring!", SAY_SAY, 3000}})
+ table.insert(fleeAnim, {func = AnimSay, args = {enemy, "I ain't gonna sit around no more!", SAY_SAY, 5000}})
+ table.insert(fleeAnim, {func = AnimTurn, args = {enemy, "Right"}})
+ table.insert(fleeAnim, {func = AnimSay, args = {enemy, "Yo, escort my buttocks!", SAY_SHOUT, 3500}})
+ table.insert(fleeAnim, {func = AnimSwitchHog, args = {natives[1]}})
+ table.insert(fleeAnim, {func = AnimWait, args = {natives[1], 1}})
+ table.insert(fleeAnim, {func = AnimDisappear, swh = false, args = {enemy, 0, 0}})
+end
+
+function SetupWaterAnim()
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "Stay there, comrades!", SAY_SHOUT, 2500}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "Come closer and die...burp!", SAY_SHOUT, 4000}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "Fiery Water?! Are you drunk again?", SAY_SHOUT, 5000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "Drunk with power, perhappss!", SAY_SHOUT, 4000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "The power of love! No, wait, the power of the aliens!", SAY_SHOUT, 7500}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "We trusted you, you fool!", SAY_SHOUT, 4000}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "Why do you keep betraying us?", SAY_SHOUT, 4000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "Why, why, why, why!", SAY_SHOUT, 4000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "I grew sick of the oppression! I brock free!", SAY_SHOUT, 6500}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "What oppression?! You were the most unoppressed member of the tribe!", SAY_SHOUT, 10000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "The opression of the elders, of course!", SAY_SHOUT, 6500}})
+ if m5DeployedNum == leaksNum then
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "You should know this more than anyone, Leaks!", SAY_SHOUT, 7000}})
+ elseif m5LeaksDead == 1 then
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "Just look at Leaks, may he rest in peace!", SAY_SHOUT, 6500}})
+ end
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "We, the youth, have to constantly prove our value...", SAY_SHOUT, 7000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "We work and work until we sweat blood...", SAY_SHOUT, 5000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "We risk our lives going through challenges...", SAY_SHOUT, 6000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "All this to please our beloved 'elders'...hick...", SAY_SHOUT, 6000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "And what do they do in the meantime? NOTHING!", SAY_SHOUT, 6000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "All they do is sit around and judge us!", SAY_SHOUT, 6000}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "You have never worked a bit in your life!", SAY_SHOUT, 6000}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "All *you* do is take long walks when everyone else works.", SAY_SHOUT, 9000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "Anyway, the aliens accept me for who I am.", SAY_SHOUT, 7000}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "We won't accept you destroying our village!", SAY_SHOUT, 7000}})
+
+ table.insert(fleeAnim, {func = AnimSay, args = {enemy, "Argh, the borrdommm!", SAY_SAY, 3000}})
+ table.insert(fleeAnim, {func = AnimSay, args = {enemy, "I have more important things to do!", SAY_SAY, 5000}})
+ table.insert(fleeAnim, {func = AnimTurn, args = {enemy, "Right"}})
+ table.insert(fleeAnim, {func = AnimSay, args = {enemy, "Comrades! Sail me away!", SAY_SHOUT, 3500}})
+ table.insert(fleeAnim, {func = AnimSwitchHog, args = {natives[1]}})
+ table.insert(fleeAnim, {func = AnimWait, args = {natives[1], 1}})
+ table.insert(fleeAnim, {func = AnimDisappear, swh = false, args = {enemy, 0, 0}})
+end
+
+function SetupWaterAnimDeployed()
+ table.insert(startAnim, {func = AnimCustomFunction, args = {enemy, CondNeedToTurn, {natives[3], enemy}}})
+ table.insert(startAnim, {func = AnimCustomFunction, args = {enemy, CondNeedToTurn, {natives[2], enemy}}})
+ table.insert(startAnim, {func = AnimCustomFunction, args = {enemy, CondNeedToTurn, {natives[1], enemy}}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "Stop, comrades!", SAY_SHOUT, 2500}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "I cannot let you go any farther...burp!", SAY_SHOUT, 5500}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "Fiery Water?! Are you drunk again?", SAY_SHOUT, 5000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "Drunk with power, perhappss!", SAY_SHOUT, 4000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "The power of love! No, wait, the power of the aliens!", SAY_SHOUT, 7500}})
+ table.insert(startAnim, {func = AnimTeleportGear, args = {enemy, unpack(enemyPos)}})
+ table.insert(startAnim, {func = AnimCustomFunction, args = {enemy, CondNeedToTurn, {natives[3], enemy}}})
+ table.insert(startAnim, {func = AnimCustomFunction, args = {enemy, CondNeedToTurn, {natives[2], enemy}}})
+ table.insert(startAnim, {func = AnimCustomFunction, args = {enemy, CondNeedToTurn, {natives[1], enemy}}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "We trusted you, you fool!", SAY_SHOUT, 4000}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "Why do you keep betraying us?", SAY_SHOUT, 4000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "Why, why, why, why!", SAY_SHOUT, 4000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "I grew sick of the oppression! I brock free!", SAY_SHOUT, 6500}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "What oppression?! You were the most unoppressed member of the tribe!", SAY_SHOUT, 10000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "The opression of the elders, of course!", SAY_SHOUT, 6500}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "Just look at Leaks, may he rest in peace!", SAY_SHOUT, 6500}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "We, the youth, have to constantly prove our value...", SAY_SHOUT, 7000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "We work and work until we sweat blood...", SAY_SHOUT, 5000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "We risk our lives going through challenges...", SAY_SHOUT, 6000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "All this to please our beloved 'elders'...hick...", SAY_SHOUT, 6000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "And what do they do in the meantime? NOTHING!", SAY_SHOUT, 6000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "All they do is sit around and judge us!", SAY_SHOUT, 6000}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "You have never worked a bit in your life!", SAY_SHOUT, 6000}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "All *you* do is take long walks when everyone else works.", SAY_SHOUT, 9000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "Anyway, the aliens accept me for who I am.", SAY_SHOUT, 7000}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "We won't accept you destroying our village!", SAY_SHOUT, 7000}})
+
+ table.insert(fleeAnim, {func = AnimSay, args = {enemy, "Argh, the borrdommm!", SAY_SAY, 3000}})
+ table.insert(fleeAnim, {func = AnimSay, args = {enemy, "I have more important things to do!", SAY_SAY, 5000}})
+ table.insert(fleeAnim, {func = AnimTurn, args = {enemy, "Right"}})
+ table.insert(fleeAnim, {func = AnimSay, args = {enemy, "Comrades! Sail me away!", SAY_SHOUT, 3500}})
+ table.insert(fleeAnim, {func = AnimSwitchHog, args = {natives[1]}})
+ table.insert(fleeAnim, {func = AnimWait, args = {natives[1], 1}})
+ table.insert(fleeAnim, {func = AnimDisappear, swh = false, args = {enemy, 0, 0}})
+end
+
+function SetupPrincessAnim()
+ table.insert(startAnim, {func = AnimCustomFunction, args = {enemy, CondNeedToTurn, {natives[3], enemy}}})
+ table.insert(startAnim, {func = AnimCustomFunction, args = {enemy, CondNeedToTurn, {natives[2], enemy}}})
+ table.insert(startAnim, {func = AnimCustomFunction, args = {enemy, CondNeedToTurn, {natives[1], enemy}}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "Oh, my! I forgot something!", SAY_SHOUT, 4000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "We need to go back!", SAY_SHOUT, 3000}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "What could you possibly forget in that cage?", SAY_SHOUT, 7000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "I don't like your tone! You're hurting me!", SAY_SHOUT, 4000}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "I'm terribly sorry!", SAY_SHOUT, 4000}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "What is it that you forgot?", SAY_SHOUT, 4000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "Uhmm, it's...uhm...my ring!", SAY_SHOUT, 4000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "It's precious to me!", SAY_SHOUT, 3000}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "We don't have time for that now!", SAY_SHOUT, 5000}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "We have to find our folk!", SAY_SHOUT, 4000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "But I want my sandals!", SAY_SHOUT, 3000}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "Sandals?! I thought you left your ring!", SAY_SHOUT, 6000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "All right, you got me...", SAY_SHOUT, 3000}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "Got you? You're acting weird...", SAY_SHOUT, 4000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "You just can't let it go, can you!", SAY_SHOUT, 5000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "All right, I'll admit it!", SAY_SHOUT, 4000}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "Admit what?", SAY_SHOUT, 2000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "You give me no choice!", SAY_SHOUT, 4000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "I can't let you go further because...", SAY_SHOUT, 6000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "I'm the spy! I've been giving you out!", SAY_SHOUT, 6000}})
+ table.insert(startAnim, {func = AnimTeleportGear, args = {enemy, unpack(enemyPos)}})
+ table.insert(startAnim, {func = AnimCustomFunction, args = {enemy, CondNeedToTurn, {natives[3], enemy}}})
+ table.insert(startAnim, {func = AnimCustomFunction, args = {enemy, CondNeedToTurn, {natives[2], enemy}}})
+ table.insert(startAnim, {func = AnimCustomFunction, args = {enemy, CondNeedToTurn, {natives[1], enemy}}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "But...they kidnapped you!", SAY_SHOUT, 4000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "Oh, that. We were just having fun!", SAY_SHOUT, 5000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "It's an ancient ritual of theirs.", SAY_SHOUT, 5000}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "Why did you do this?", SAY_SHOUT, 4000}})
+ if m5ChiefDead == 1 then
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "Why did you kill your father?", SAY_SHOUT, 5000}})
+ end
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "Do you have any idea what it's like in the village for a woman?", SAY_SHOUT, 10000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "How would you like being discriminated against?", SAY_SHOUT, 7000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "Not being able to fight, hunt...", SAY_SHOUT, 5000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "Gathering fruits all day long...", SAY_SHOUT, 5000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "Doing stuff a monkey could do...", SAY_SHOUT, 5000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "Always being considered weak and fragile...", SAY_SHOUT, 6000}})
+ if m5DeployedNum == girlNum then
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "In case you haven't noticed, I'm a woman, too!", SAY_SHOUT, 8000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "Yes, but you're...different!", SAY_SHOUT, 6000}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "Of course I am...", SAY_SHOUT, 3000}})
+ end
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "The aliens respect me, even worship me!", SAY_SHOUT, 6000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "I'm living a dream!", SAY_SHOUT, 3000}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "Well, you're about to wake up!", SAY_SHOUT, 5000}})
+
+ table.insert(fleeAnim, {func = AnimSay, args = {enemy, "Hmm...it's going slower than expected.", SAY_SAY, 5000}})
+ table.insert(fleeAnim, {func = AnimSay, args = {enemy, "I am going to leave the kids play by themselves.", SAY_SAY, 6000}})
+ table.insert(fleeAnim, {func = AnimTurn, args = {enemy, "Right"}})
+ table.insert(fleeAnim, {func = AnimSay, args = {enemy, "Alien! I wish to be moved!", SAY_SHOUT, 4000}})
+ table.insert(fleeAnim, {func = AnimSwitchHog, args = {natives[1]}})
+ table.insert(fleeAnim, {func = AnimWait, args = {natives[1], 1}})
+ table.insert(fleeAnim, {func = AnimDisappear, swh = false, args = {enemy, 0, 0}})
+end
+
+function SetupCyborgAnim()
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "Stop right there, puny worms!", SAY_SHOUT, 4000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "Stay away from our weapons!", SAY_SHOUT, 4000}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "We come in peace! Just let our friends go!", SAY_SHOUT, 5500}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "I'm afraid we cannot afford that...", SAY_SHOUT, 4500}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "You see, hedgehog spikes are very very valuable.", SAY_SHOUT, 6500}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "Very valuable, haha!", SAY_SHOUT, 3500}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "Don't you dare harm our tribe!", SAY_SHOUT, 5000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "It's a shame, really!", SAY_SHOUT, 4000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "I regret to end your little odyssey.", SAY_SHOUT, 5000}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "It was fun to watch...", SAY_SHOUT, 3500}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "The way you handled your little internal conflicts...", SAY_SHOUT, 6500}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "Did you really think that we needed the help of one of you?", SAY_SHOUT, 7500}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "You should have known that we don't rely on meatbags!", SAY_SHOUT, 7500}})
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "It was fun to watch though...", SAY_SHOUT, 3500}})
+ if m5Choice == choiceEliminate then
+ table.insert(startAnim, {func = AnimSay, args = {enemy, "Heck, you even executed one of your own!", SAY_SHOUT, 6000}})
+ end
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "It was all a trick?!", SAY_SHOUT, 3000}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "Some sick game of yours?!", SAY_SHOUT, 4000}})
+ table.insert(startAnim, {func = AnimSay, args = {natives[1], "We won't let you hurt any more of us!", SAY_SHOUT, 6000}})
+
+ table.insert(fleeAnim, {func = AnimSay, args = {enemy, "Entered boredom phase! Discrepancies detected...", SAY_SAY, 5000}})
+ table.insert(fleeAnim, {func = AnimSay, args = {enemy, "Initiate escape wish!", SAY_SAY, 6000}})
+ table.insert(fleeAnim, {func = AnimTurn, args = {enemy, "Right"}})
+ table.insert(fleeAnim, {func = AnimSay, args = {enemy, "Running displacement algorithm...", SAY_SHOUT, 4000}})
+ table.insert(fleeAnim, {func = AnimSwitchHog, args = {natives[1]}})
+ table.insert(fleeAnim, {func = AnimWait, args = {natives[1], 1}})
+ table.insert(fleeAnim, {func = AnimDisappear, swh = false, args = {enemy, 0, 0}})
+end
+
+function SetupFinalAnim()
+ local found = 0
+ local gears = {}
+ for i = nativesLeft, 1, -1 do
+ if band(GetState(natives[i]), gstDrowning) == 0 then
+ found = found + 1
+ gears[found] = natives[i]
+ end
+ end
+ if found == 0 then
+ return
+ else
+ for i = 1, found do
+ table.insert(finalAnim, {func = AnimCustomFunction, args = {gears[1], CondNeedToTurn, {cyborg, gears[i]}}})
+ end
+ table.insert(finalAnim, {func = AnimSay, args = {cyborg, "Nice work, meatbags!", SAY_SAY, 3000}})
+ table.insert(finalAnim, {func = AnimSay, args = {cyborg, "You're on your way to freeing your tribe!", SAY_SAY, 5500}})
+ table.insert(finalAnim, {func = AnimSay, args = {gears[1], "Do you know where they are?", SAY_SAY, 4000}})
+ table.insert(finalAnim, {func = AnimSay, args = {gears[found], "We need to hurry!", SAY_SAY, 3000}})
+ table.insert(finalAnim, {func = AnimSay, args = {cyborg, "Haha! Come!", SAY_SAY, 2000}})
+ table.insert(finalAnim, {func = AnimJump, args = {cyborg, "high"}})
+ table.insert(finalAnim, {func = AnimDisappear, args = {cyborg, GetGearPosition(cyborg)}})
+ for i = 1, found do
+ table.insert(finalAnim, {func = HideHedge, swh = false, args = {gears[i]}})
+ end
+ table.insert(finalAnim, {func = SetState, swh = false, args = {cyborg, gstInvisible}})
+ end
+end
+
+
+--------------------------Anim skip functions--------------------------
+function AfterStartAnim()
+ SetGearMessage(natives[1], 0)
+ ShowMission("Long Live The Queen", "Closing in", "Defeat the enemy!|The leader seems scared, he will probably flee.", 1, 0)
+ SetHealth(SpawnHealthCrate(2207, 44), 25)
+ SetHealth(SpawnHealthCrate(519, 1519), 25)
+ SetHealth(SpawnHealthCrate(826, 895), 25)
+ SpawnUtilityCrate(701, 1046, amGirder, 3)
+ TurnTimeLeft = TurnTime
+end
+
+function SkipAnim(anim)
+ if anim == startAnim then
+ SetGearPosition(enemy, unpack(enemyPos))
+ end
+ if GetHogTeamName(CurrentHedgehog) ~= loc("Natives") then
+ TurnTimeLeft = 0
+ end
+ AnimWait(enemy, 1)
+end
+
+function AfterFleeAnim()
+ SetHealth(SpawnHealthCrate(130, 455), 25)
+ SetHealth(SpawnHealthCrate(2087, 50), 25)
+ SetHealth(SpawnHealthCrate(2143, 54), 25)
+ SetHealth(SpawnHealthCrate(70, 1308), 25)
+ SetGearMessage(CurrentHedgehog, 0)
+ HideHedge(enemy)
+ ShowMission("Long Live The Queen", "Coward", "The leader escaped. Defeat the rest of the aliens!", 1, 0)
+ TurnTimeLeft = TurnTime
+end
+
+function AfterLeaderDeadAnim()
+ SetHealth(SpawnHealthCrate(130, 455), 25)
+ SetHealth(SpawnHealthCrate(2087, 50), 25)
+ SetHealth(SpawnHealthCrate(2143, 54), 25)
+ SetHealth(SpawnHealthCrate(70, 1308), 25)
+ ShowMission("Long Live The Queen", "Bullseye", "Good Job! Defeat the rest of the aliens!", 1, 0)
+ TurnTimeLeft = 0
+end
+-----------------------------Events------------------------------------
+function CheckTurnsOver()
+ return TotalRounds > 6
+end
+
+function DoTurnsOver()
+ SetGearMessage(CurrentHedgehog, 0)
+ enemyFled = "1"
+ AddAnim(fleeAnim)
+ AddFunction({func = AfterFleeAnim, args = {}})
+ RemoveEventFunc(CheckGearDead, {enemy})
+end
+
+function CheckNativesDead()
+ return nativesLeft == 0
+end
+
+function DoNativesDead()
+ RemoveEventFunc(CheckTurnsOver)
+ RemoveEventFunc(CheckGearDead)
+ RemoveEventFunc(CheckCyborgsDead)
+ AddCaption("...and the cyborgs took over the island.")
+ TurnTimeLeft = 0
+end
+
+function CheckCyborgsDead()
+ return (cyborgsLeft == 0 and (gearDead[enemy] == true or enemyFled == "1"))
+end
+
+function KillEnemy()
+ if enemyFled == "1" then
+ ParseCommand("teamgone " .. loc("Leaderbot"))
+ end
+ ParseCommand("teamgone " .. loc("011101001"))
+ TurnTimeLeft = 0
+end
+
+function DoCyborgsDead()
+ SaveCampaignVariables()
+ RestoreHedge(cyborg)
+ PlaceGirder(3292, 922, 4)
+ SetGearPosition(cyborg, 3290, 902)
+ SetupFinalAnim()
+ AddAnim(finalAnim)
+ AddFunction({func = KillEnemy, args = {}})
+end
+
+function DoLeaderDead()
+ leaderDead = true
+ SetGearMessage(CurrentHedgehog, 0)
+ SetupLeaderDeadAnim()
+ AddAnim(leaderDeadAnim)
+ AddFunction({func = AfterLeaderDeadAnim, args = {}})
+ RemoveEventFunc(CheckTurnsOver)
+end
+
+function CheckGearsDead(gearList)
+ for i = 1, # gearList do
+ if gearDead[gearList[i]] ~= true then
+ return false
+ end
+ end
+ return true
+end
+
+function CheckGearDead(gear)
+ return gearDead[gear]
+end
+
+-----------------------------Misc--------------------------------------
+function HideHedge(hedge)
+ if hedgeHidden[hedge] ~= true then
+ HideHog(hedge)
+ hedgeHidden[hedge] = true
+ end
+end
+
+function RestoreHedge(hedge)
+ if hedgeHidden[hedge] == true then
+ RestoreHog(hedge)
+ hedgeHidden[hedge] = false
+ end
+end
+
+function GetVariables()
+ progress = tonumber(GetCampaignVar("Progress"))
+ m5DeployedNum = tonumber(GetCampaignVar("M5DeployedNum"))
+ m2Choice = tonumber(GetCampaignVar("M2Choice"))
+ m5Choice = tonumber(GetCampaignVar("M5Choice"))
+ m2DenseDead = tonumber(GetCampaignVar("M2DenseDead"))
+ m4DenseDead = tonumber(GetCampaignVar("M4DenseDead"))
+ m5DenseDead = tonumber(GetCampaignVar("M5DenseDead"))
+ m4LeaksDead = tonumber(GetCampaignVar("M4LeaksDead"))
+ m5LeaksDead = tonumber(GetCampaignVar("M5LeaksDead"))
+ m4ChiefDead = tonumber(GetCampaignVar("M4ChiefDead"))
+ m5ChiefDead = tonumber(GetCampaignVar("M5ChiefDead"))
+ m4WaterDead = tonumber(GetCampaignVar("M4WaterDead"))
+ m5WaterDead = tonumber(GetCampaignVar("M5WaterDead"))
+ m4BuffaloDead = tonumber(GetCampaignVar("M4BuffaloDead"))
+ m5BuffaloDead = tonumber(GetCampaignVar("M5BuffaloDead"))
+ m5WiseDead = tonumber(GetCampaignVar("M5WiseDead"))
+ m5GirlDead = tonumber(GetCampaignVar("M5GirlDead"))
+end
+
+function SaveCampaignVariables()
+ for i = 1, 4 do
+ if gearDead[origNatives[i]] ~= true then
+ SaveCampaignVar(nativeSaveNames[i], "0")
+ else
+ SaveCampaignVar(nativeSaveNames[i], "1")
+ end
+ end
+
+ SaveCampaignVar("M8DeployedLeader", deployedLeader)
+ SaveCampaignVar("M8PrincessLeader", princessLeader)
+ SaveCampaignVar("M8EnemyFled", enemyFled)
+ SaveCampaignVar("M8Scene", "" .. scene)
+ if progress and progress<8 then
+ SaveCampaignVar("Progress", "8")
+ end
+end
+
+function SetupPlace()
+ HideHedge(cyborg)
+ SetHogHat(natives[1], nativeHats[m5DeployedNum])
+ SetHogName(natives[1], nativeNames[m5DeployedNum])
+
+ if m5DeployedNum == denseNum then
+ dense = natives[1]
+ else
+ dense = enemy
+ end
+
+ if m2Choice == choiceAccepted and m5Choice ~= choiceEliminate then
+ scene = denseScene
+ SetHogHat(enemy, nativeHats[denseNum])
+ SetHogName(enemy, nativeNames[denseNum])
+ dense = enemy
+ elseif m2Choice == choiceAccepted then
+ scene = cyborgScene
+ SetHogHat(enemy, "cyborg2")
+ SetHogName(enemy, loc("Nancy Screw"))
+ elseif m5Choice == choiceEliminate then
+ scene = princessScene
+ SetHogHat(enemy, "tiara")
+ SetHogName(enemy, loc("Fell From Heaven"))
+ else
+ scene = waterScene
+ SetHogHat(enemy, nativeHats[waterNum])
+ SetHogName(enemy, nativeNames[waterNum])
+ end
+ for i = 1, 4 do
+ if GetHogName(natives[i]) == GetHogName(enemy) then
+ AnimSetGearPosition(enemy, GetGearPosition(natives[i]))
+ DeleteGear(natives[i])
+ DeleteGear(cyborgs[cyborgsLeft])
+ end
+ end
+
+ SpawnAmmoCrate(34, 395, amBee, 2)
+ SpawnAmmoCrate(33, 374, amRCPlane, 1)
+ SpawnAmmoCrate(74, 393, amAirAttack, 3)
+ SpawnAmmoCrate(1313, 1481, amBazooka, 8)
+ SpawnAmmoCrate(80, 360, amSniperRifle, 4)
+ SpawnAmmoCrate(1037, 1494, amShotgun, 7)
+ SpawnAmmoCrate(1037, 1472, amMolotov, 3)
+ SpawnAmmoCrate(1146, 1503, amMortar, 8)
+
+ SpawnUtilityCrate(1147, 1431, amPortalGun, 2)
+ SpawnUtilityCrate(1219, 1542, amRope, 5)
+ SpawnUtilityCrate(1259, 1501, amJetpack, 2)
+end
+
+function SetupEvents()
+ AddNewEvent(CheckNativesDead, {}, DoNativesDead, {}, 0)
+ AddNewEvent(CheckGearDead, {enemy}, DoLeaderDead, {}, 0)
+ AddNewEvent(CheckTurnsOver, {}, DoTurnsOver, {}, 0)
+ AddNewEvent(CheckCyborgsDead, {}, DoCyborgsDead, {}, 0)
+end
+
+function SetupAmmo()
+ AddAmmo(natives[1], amPickHammer, 2)
+ AddAmmo(natives[1], amBazooka, 0)
+ AddAmmo(natives[1], amGrenade, 0)
+ AddAmmo(natives[1], amShotgun, 0)
+ AddAmmo(natives[1], amAirStrike, 0)
+ AddAmmo(natives[1], amMolotov, 0)
+end
+
+function AddHogs()
+ AddTeam(loc("Natives"), 29439, "Bone", "Island", "HillBilly", "cm_birdy")
+ for i = 7, 9 do
+ natives[i-6] = AddHog(nativeNames[i], 0, 100, nativeHats[i])
+ origNatives[i-6] = natives[i-6]
+ end
+ natives[4] = AddHog(loc("Fell From Heaven"), 0, 133, "tiara")
+ origNatives[4] = natives[4]
+ nativesLeft = nativesNum
+
+ AddTeam(loc("Beep Loopers"), 14483456, "ring", "UFO", "Robot", "cm_star")
+ for i = 1, cyborgsTeamNum[1] do
+ cyborgs[i] = AddHog(cyborgNames[i], cyborgsDif[i], cyborgsHealth[i], "cyborg2")
+ end
+
+ AddTeam(loc("Corporationals"), 14483456, "ring", "UFO", "Robot", "cm_star")
+ for i = cyborgsTeamNum[1] + 1, cyborgsNum do
+ cyborgs[i] = AddHog(cyborgNames[i], cyborgsDif[i], cyborgsHealth[i], "cyborg2")
+ end
+ cyborgsLeft = cyborgsTeamNum[1] + cyborgsTeamNum[2]
+
+ AddTeam(loc("Leaderbot"), 14483456, "ring", "UFO", "Robot", "cm_star")
+ enemy = AddHog(loc("Name"), 2, 200, "cyborg1")
+
+ AddTeam(loc("011101001"), 14483456, "ring", "UFO", "Robot", "cm_star")
+ cyborg = AddHog(loc("Unit 334a$7%;.*"), 0, 200, "cyborg1")
+
+ SetGearPosition(cyborg, 0, 0)
+
+ for i = 1, nativesNum do
+ AnimSetGearPosition(natives[i], unpack(nativePos[i]))
+ end
+
+ AnimSetGearPosition(enemy, unpack(enemyPos))
+ AnimTurn(enemy, "Left")
+
+ for i = 1, cyborgsNum do
+ AnimSetGearPosition(cyborgs[i], unpack(cyborgsPos[i]))
+ AnimTurn(cyborgs[i], cyborgsDir[i])
+ end
+end
+
+function CondNeedToTurn(hog1, hog2)
+ xl, xd = GetX(hog1), GetX(hog2)
+ if xl > xd then
+ AnimInsertStepNext({func = AnimTurn, args = {hog1, "Left"}})
+ AnimInsertStepNext({func = AnimTurn, args = {hog2, "Right"}})
+ elseif xl < xd then
+ AnimInsertStepNext({func = AnimTurn, args = {hog2, "Left"}})
+ AnimInsertStepNext({func = AnimTurn, args = {hog1, "Right"}})
+ end
+end
+
+-----------------------------Main Functions----------------------------
+
+function onGameInit()
+ Seed = 0
+ GameFlags = gfDisableGirders + gfDisableLandObjects
+ TurnTime = 60000
+ CaseFreq = 0
+ MinesNum = 0
+ MinesTime = 3000
+ Explosives = 0
+ Delay = 10
+ MapGen = 2
+ Theme = "Hell"
+ SuddenDeathTurns = 20
+
+ for i = 1, #map do
+ ParseCommand('draw ' .. map[i])
+ end
+
+ GetVariables()
+ AnimInit()
+ AddHogs()
+end
+
+function onGameStart()
+ SetupAmmo()
+ SetupPlace()
+ AnimationSetup()
+ SetupEvents()
+ AddAnim(startAnim)
+ AddFunction({func = AfterStartAnim, args = {}})
+end
+
+function onGameTick()
+ AnimUnWait()
+ if ShowAnimation() == false then
+ return
+ end
+ ExecuteAfterAnimations()
+ CheckEvents()
+end
+
+function onGearDelete(gear)
+ local toRemove = nil
+ gearDead[gear] = true
+ if GetGearType(gear) == gtHedgehog then
+ if GetHogTeamName(gear) == loc("Beep Loopers") or GetHogTeamName(gear) == loc("Corporationals") then
+ cyborgsLeft = cyborgsLeft - 1
+ elseif GetHogTeamName(gear) == loc("Natives") then
+ for i = 1, nativesLeft do
+ if natives[i] == gear then
+ toRemove = i
+ end
+ end
+ table.remove(natives, toRemove)
+ nativesLeft = nativesLeft - 1
+ end
+ end
+end
+
+function onAmmoStoreInit()
+ SetAmmo(amBaseballBat, 9, 0, 0, 0)
+ SetAmmo(amFirePunch, 9, 0, 0, 0)
+ SetAmmo(amDEagle, 9, 0, 0, 0)
+ SetAmmo(amSkip, 9, 0, 0, 0)
+ SetAmmo(amSwitch, 9, 0, 0, 0)
+ SetAmmo(amBazooka, 9, 0, 0, 0)
+ SetAmmo(amGrenade, 9, 0, 0, 0)
+ SetAmmo(amAirStrike, 1, 0, 0, 0)
+ SetAmmo(amMolotov, 5, 0, 0, 0)
+ SetAmmo(amShotgun, 9, 0, 0, 0)
+end
+
+function onNewTurn()
+ if AnimInProgress() then
+ TurnTimeLeft = -1
+ return
+ end
+ if GetHogTeamName(CurrentHedgehog) == loc("011101001") then
+ TurnTimeLeft = 0
+ end
+end
+
+function onPrecise()
+ if GameTime > 2500 and AnimInProgress() then
+ SetAnimSkip(true)
+-- else
+-- DeleteGear(cyborgs[1])
+-- table.remove(cyborgs, 1)
+-- if cyborgsLeft == 0 then
+-- DeleteGear(enemy)
+-- end
+ end
+end
Binary file share/hedgewars/Data/Missions/Campaign/A_Classic_Fairytale/shadow.hwp has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Missions/Campaign/A_Classic_Fairytale/shadow.lua Mon Jul 01 23:23:22 2013 +0300
@@ -0,0 +1,969 @@
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Animate.lua")
+
+-----------------------------Constants---------------------------------
+startStage = 0
+spyStage = 1
+wave1Stage = 2
+wave2Stage = 3
+cyborgStage = 4
+ramonStage = 5
+aloneStage = 6
+duoStage = 7
+interSpyStage = 8
+interWeakStage = 9
+acceptedReturnStage = 10
+refusedReturnStage = 11
+attackedReturnStage = 12
+loseStage = 13
+
+ourTeam = 0
+weakTeam = 1
+strongTeam = 2
+cyborgTeam = 3
+
+leaksNr = 0
+denseNr = 1
+
+choiceAccept = 1
+choiceRefuse = 2
+choiceAttack = 3
+
+HogNames = {loc("Brainiac"), loc("Corpsemonger"), loc("Femur Lover"), loc("Glark"), loc("Bonely"), loc("Rot Molester"), loc("Bloodrocutor"), loc("Muscle Dissolver"), loc("Bloodsucker")}
+
+---POSITIONS---
+
+cannibalPos = {{3108, 1127},
+ {2559, 1080}, {3598, 1270}, {3293, 1177}, {2623, 1336},
+ {3418, 1336}, {3447, 1335}, {3481, 1340}, {3507, 1324}}
+densePos = {2776, 1177}
+leaksPos = {2941, 1172}
+cyborgPos = {1113, 1818}
+
+---Animations
+
+startDialogue = {}
+weaklingsAnim = {}
+stronglingsAnim = {}
+acceptedAnim = {}
+acceptedSurvivedFinalAnim = {}
+acceptedDiedFinalAnim = {}
+refusedAnim = {}
+refusedFinalAnim = {}
+attackedAnim = {}
+attackedFinalAnim = {}
+
+-----------------------------Variables---------------------------------
+lastHogTeam = ourTeam
+lastOurHog = leaksNr
+lastEnemyHog = 0
+stage = 0
+choice = 0
+
+brainiacDead = false
+cyborgHidden = false
+leaksHidden = false
+denseHidden = false
+cyborgAttacked = false
+retryReturn = false
+shotgunTaken = false
+grenadeTaken = false
+spikyDead = false
+ramonDead = false
+denseDead = false
+leaksDead = false
+ramonHidden = false
+spikyHidden = false
+grenadeUsed = false
+shotgunUsed = false
+
+
+hogNr = {}
+cannibalDead = {}
+isHidden = {}
+
+
+--------------------------Anim skip functions--------------------------
+function AfterRefusedAnim()
+ SpawnUtilityCrate(2045, 1575, amSwitch)
+ SpawnUtilityCrate(2365, 1495, amShotgun)
+ SpawnUtilityCrate(2495, 1519, amGrenade)
+ SpawnUtilityCrate(2620, 1524, amRope)
+ ShowMission(loc("The Shadow Falls"), loc("The Showdown"), loc("Save Leaks A Lot!|Hint: The Switch utility might be of help to you."), 1, 6000)
+ RemoveEventFunc(CheckDenseDead)
+ AddEvent(CheckStronglingsDead, {}, DoStronglingsDeadRefused, {}, 0)
+ AddAmmo(cannibals[6], amGrenade, 1)
+ AddAmmo(cannibals[7], amGrenade, 1)
+ AddAmmo(cannibals[8], amGrenade, 1)
+ AddAmmo(cannibals[9], amGrenade, 1)
+ stage = ramonStage
+ SwitchHog(cannibals[9])
+ FollowGear(ramon)
+ TurnTimeLeft = 0
+ SetGearMessage(ramon, 0)
+ SetGearMessage(leaks, 0)
+ AnimWait(ramon, 1)
+ AddFunction({func = HideHog, args = {cyborg}})
+end
+
+function SkipRefusedAnim()
+ RefusedStart()
+ AnimSetGearPosition(dense, 2645, 1146)
+ AnimSetGearPosition(ramon, 2218, 1675)
+ AnimSetGearPosition(spiky, 2400, 1675)
+end
+
+function AfterStartDialogue()
+ stage = spyStage
+ ShowMission(loc("The Shadow Falls"), loc("Play with me!"), loc("Defend yourself!|Hint: You can get tips on using weapons by moving your mouse over them in the weapon selection menu"), 1, 6000)
+ TurnTimeLeft = TurnTime
+end
+
+
+function StartSkipFunc()
+ SetState(cannibals[1], 0)
+ AnimTurn(leaks, "Right")
+ AnimSwitchHog(leaks)
+ SetInputMask(0xFFFFFFFF)
+end
+
+function AfterWeaklingsAnim()
+ AddAmmo(cannibals[2], amShotgun, 1)
+ AddAmmo(cannibals[2], amGrenade, 1)
+ AddAmmo(cannibals[3], amShotgun, 1)
+ AddAmmo(cannibals[3], amGrenade, 1)
+ AddAmmo(cannibals[4], amShotgun, 1)
+ AddAmmo(cannibals[4], amGrenade, 1)
+ AddAmmo(cannibals[5], amShotgun, 1)
+ AddAmmo(cannibals[5], amGrenade, 1)
+ AddAmmo(leaks, amSkip, 4)
+ AddAmmo(dense, amSkip, 4)
+ AddEvent(CheckWeaklingsKilled, {}, DoWeaklingsKilled, {}, 0)
+ SetHealth(SpawnHealthCrate(2757, 1030), 50)
+ SetHealth(SpawnHealthCrate(2899, 1009), 50)
+ stage = wave1Stage
+ SwitchHog(dense)
+ SetGearMessage(dense, 0)
+ SetGearMessage(leaks, 0)
+ TurnTimeLeft = TurnTime
+ ShowMission(loc("The Shadow Falls"), loc("Why do you not like me?"), loc("Obliterate them!|Hint: You might want to take cover..."), 1, 6000)
+end
+
+function SkipWeaklingsAnim()
+ for i = 2, 5 do
+ if isHidden[cannibals[i]] == true then
+ RestoreHog(cannibals[i])
+ isHidden[cannibals[i]] = false
+ end
+ AnimSetGearPosition(cannibals[i], unpack(cannibalPos[i]))
+ SetState(cannibals[i], 0)
+ end
+ SetInputMask(0xFFFFFFFF)
+end
+
+function AfterStronglingsAnim()
+ stage = cyborgStage
+ ShowMission(loc("The Shadow Falls"), loc("The Dilemma"), loc("Choose your side! If you want to join the strange man, walk up to him.|Otherwise, walk away from him. If you decide to att...nevermind..."), 1, 8000)
+ AddEvent(CheckChoice, {}, DoChoice, {}, 0)
+ AddEvent(CheckRefuse, {}, DoRefuse, {}, 0)
+ AddEvent(CheckAccept, {}, DoAccept, {}, 0)
+ AddEvent(CheckConfront, {}, DoConfront, {}, 0)
+ AddAmmo(dense, amSwitch, 0)
+ AddAmmo(dense, amSkip, 0)
+ AddAmmo(leaks, amSwitch, 0)
+ AddAmmo(leaks, amSkip, 0)
+ SetHealth(SpawnHealthCrate(2557, 1030), 50)
+ SetHealth(SpawnHealthCrate(3599, 1009), 50)
+ TurnTimeLeft = 0
+end
+
+function SkipStronglingsAnim()
+ for i = 6, 9 do
+ if isHidden[cannibals[i]] == true then
+ RestoreHog(cannibals[i])
+ isHidden[cannibals[i]] = false
+ end
+ AnimSetGearPosition(cannibals[i], unpack(cannibalPos[i]))
+ SetState(cannibals[i], 0)
+ end
+ if cyborgHidden == true then
+ RestoreHog(cyborg)
+ cyborgHidden = false
+ end
+ SetState(cyborg, 0)
+ SetState(dense, 0)
+ AnimSetGearPosition(dense, 1350, 1315)
+ FollowGear(dense)
+ HogTurnLeft(dense, true)
+ AnimSetGearPosition(cyborg, 1250, 1315)
+ SwitchHog(dense)
+ SetInputMask(0xFFFFFFFF)
+end
+
+function RestartReturnAccepted()
+ retryReturn = false
+ AnimSetGearPosition(dense, 1350, 1310)
+ AddAmmo(dense, amGirder, 2)
+ AddAmmo(dense, amParachute, 2)
+ ShowMission(loc("The Shadow Falls"), loc("The walk of Fame"), loc("Return to Leaks A Lot! If you get stuck, press [Precise] to try again!"), 1, 6000)
+ RemoveEventFunc(CheckNeedGirder)
+ RemoveEventFunc(CheckNeedWeapons)
+ AddEvent(CheckNeedGirder, {}, DoNeedGirder, {}, 0)
+ AddEvent(CheckNeedWeapons, {}, DoNeedWeapons, {}, 0)
+end
+
+
+function AfterAcceptedAnim()
+ stage = acceptedReturnStage
+ SpawnAmmoCrate(1370, 810, amGirder)
+ SpawnAmmoCrate(1300, 810, amParachute)
+ ShowMission(loc("The Shadow Falls"), loc("The walk of Fame"), loc("Return to Leaks A Lot! If you get stuck, press [Precise] to try again!"), 1, 6000)
+ AddEvent(CheckTookWeapons, {}, DoTookWeapons, {}, 0)
+ AddEvent(CheckNeedGirder, {}, DoNeedGirder, {}, 0)
+ AddEvent(CheckNeedWeapons, {}, DoNeedWeapons, {}, 0)
+ AddEvent(CheckRestartReturnAccepted, {}, RestartReturnAccepted, {}, 1)
+ RemoveEventFunc(CheckDenseDead)
+ SwitchHog(dense)
+ AnimWait(dense, 1)
+ AddFunction({func = HideHog, args = {cyborg}})
+end
+
+function SkipAcceptedAnim()
+ AnimSetGearPosition(cyborg, unpack(cyborgPos))
+ SetState(cyborg, gstInvisible)
+ AnimSwitchHog(dense)
+ SetInputMask(0xFFFFFFFF)
+end
+
+function AfterAttackedAnim()
+ stage = aloneStage
+ ShowMission(loc("The Shadow Falls"), loc("The Individualist"), loc("Defeat the cannibals!|Grenade hint: set the timer with [1-5], aim with [Up]/[Down] and hold [Space] to set power"), 1, 8000)
+ AddAmmo(cannibals[6], amGrenade, 1)
+ AddAmmo(cannibals[6], amFirePunch, 0)
+ AddAmmo(cannibals[6], amBaseballBat, 0)
+ AddAmmo(cannibals[7], amGrenade, 1)
+ AddAmmo(cannibals[7], amFirePunch, 0)
+ AddAmmo(cannibals[7], amBaseballBat, 0)
+ AddAmmo(cannibals[8], amGrenade, 1)
+ AddAmmo(cannibals[8], amFirePunch, 0)
+ AddAmmo(cannibals[8], amBaseballBat, 0)
+ AddAmmo(cannibals[9], amGrenade, 1)
+ AddAmmo(cannibals[9], amFirePunch, 0)
+ AddAmmo(cannibals[9], amBaseballBat, 0)
+ SetGearMessage(leaks, 0)
+ TurnTimeLeft = TurnTime
+ AddEvent(CheckStronglingsDead, {}, DoStronglingsDeadAttacked, {}, 0)
+ SwitchHog(leaks)
+ AnimWait(dense, 1)
+ AddFunction({func = HideHog, args = {cyborg}})
+end
+
+function SkipAttackedAnim()
+ if denseDead == false then
+ DeleteGear(dense)
+ end
+ SpawnAmmoCrate(2551, 994, amGrenade)
+ SpawnAmmoCrate(3551, 994, amGrenade)
+ SpawnAmmoCrate(3392, 1101, amShotgun)
+ SpawnAmmoCrate(3192, 1101, amShotgun)
+ AnimSetGearPosition(cyborg, unpack(cyborgPos))
+ SetState(cyborg, gstInvisible)
+ AnimSwitchHog(leaks)
+ SetInputMask(0xFFFFFFFF)
+end
+
+
+-----------------------------Animations--------------------------------
+
+function SpawnCrates()
+ SpawnAmmoCrate(2551, 994, amGrenade)
+ SpawnAmmoCrate(3551, 994, amGrenade)
+ SpawnAmmoCrate(3392, 1101, amShotgun)
+ SpawnAmmoCrate(3192, 1101, amShotgun)
+ return true
+end
+
+function EmitDenseClouds(anim, dir)
+ local dif
+ if dir == "Left" then
+ dif = 10
+ else
+ dif = -10
+ end
+ AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
+ AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
+ AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
+ AnimInsertStepNext({func = AnimWait, args = {dense, 800}})
+ AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
+ AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
+ AnimInsertStepNext({func = AnimWait, args = {dense, 800}})
+ AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
+end
+
+function BlowDenseCloud()
+ AnimInsertStepNext({func = DeleteGear, args = {dense}, swh = false})
+ AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense), GetY(dense), vgtBigExplosion, 0, true}, swh = false})
+ AnimInsertStepNext({func = AnimWait, args = {dense, 1200}})
+ AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + 20, GetY(dense), vgtExplosion, 0, true}, swh = false})
+ AnimInsertStepNext({func = AnimWait, args = {dense, 100}})
+ AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + 10, GetY(dense), vgtExplosion, 0, true}, swh = false})
+ AnimInsertStepNext({func = AnimWait, args = {dense, 100}})
+ AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) - 10, GetY(dense), vgtExplosion, 0, true}, swh = false})
+ AnimInsertStepNext({func = AnimWait, args = {dense, 100}})
+ AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) - 20, GetY(dense), vgtExplosion, 0, true}, swh = false})
+end
+
+function SetupAcceptedSurvivedFinalAnim()
+ table.insert(acceptedSurvivedFinalAnim, {func = AnimCustomFunction, args = {dense, CondNeedToTurn, {leaks, dense}}})
+ table.insert(acceptedSurvivedFinalAnim, {func = AnimSay, args = {leaks, loc("Pfew! That was close!"), SAY_SAY, 3000}})
+ if grenadeUsed and shotgunUsed then
+ table.insert(acceptedSurvivedFinalAnim, {func = AnimSay, args = {leaks, loc("Where did you get the exploding apples and the magic bow that shoots many arrows?"), SAY_SAY, 9000}})
+ elseif grenadeUsed then
+ table.insert(acceptedSurvivedFinalAnim, {func = AnimSay, args = {leaks, loc("Where did you get the exploding apples?"), SAY_SAY, 6000}})
+ elseif shotgunUsed then
+ table.insert(acceptedSurvivedFinalAnim, {func = AnimSay, args = {leaks, loc("Where did you get the magic bow that shoots many arrows?"), SAY_SAY, 8000}})
+ else
+ table.insert(acceptedSurvivedFinalAnim, {func = AnimSay, args = {leaks, loc("Did you warn the village?"), SAY_SAY, 4000}})
+ table.insert(acceptedSurvivedFinalAnim, {func = AnimSay, args = {dense, loc("No, I came back to help you out..."), SAY_SAY, 5000}})
+ end
+ if grenadeUsed or shotgunUsed then
+ table.insert(acceptedSurvivedFinalAnim, {func = AnimSay, args = {dense, loc("Uhm...I met one of them and took his weapons."), SAY_SAY, 5000}})
+ end
+ table.insert(acceptedSurvivedFinalAnim, {func = AnimSay, args = {dense, loc("We should head back to the village now."), SAY_SAY, 5000}})
+end
+
+function AnimationSetup()
+ table.insert(startDialogue, {func = AnimWait, args = {dense, 4000}})
+ table.insert(startDialogue, {func = AnimCaption, args = {leaks, loc("After the shock caused by the enemy spy, Leaks A Lot and Dense Cloud went hunting to relax."), 6000}})
+ table.insert(startDialogue, {func = AnimCaption, args = {leaks, loc("Little did they know that this hunt will mark them forever..."), 4000}})
+ table.insert(startDialogue, {func = AnimSay, args = {leaks, loc("I have no idea where that mole disappeared...Can you see it?"), SAY_SAY, 9000}})
+ table.insert(startDialogue, {func = AnimSay, args = {dense, loc("Nope. It was one fast mole, that's for sure."), SAY_SAY, 5000}})
+ table.insert(startDialogue, {func = AnimCustomFunction, args = {dense, EmitDenseClouds, {startDialogue, "Right"}}})
+ table.insert(startDialogue, {func = AnimWait, args = {dense, 2000}})
+ table.insert(startDialogue, {func = AnimSay, args = {leaks, loc("Please, stop releasing your \"smoke signals\"!"), SAY_SAY, 5000}})
+ table.insert(startDialogue, {func = AnimSay, args = {leaks, loc("You're terrorizing the forest...We won't catch anything like this!"), SAY_SAY, 6000}})
+ table.insert(startDialogue, {func = AnimSay, args = {leaks, loc("..."), SAY_THINK, 1000}})
+ table.insert(startDialogue, {func = AnimGiveState, args = {cannibals[1], 0}, swh = false})
+ table.insert(startDialogue, {func = AnimOutOfNowhere, args = {cannibals[1], unpack(cannibalPos[1])}, swh = false})
+ table.insert(startDialogue, {func = AnimTurn, args = {leaks, "Right"}})
+ table.insert(startDialogue, {func = AnimTurn, args = {cannibals[1], "Right"}})
+ table.insert(startDialogue, {func = AnimWait, args = {cannibals[1], 1000}})
+ table.insert(startDialogue, {func = AnimTurn, args = {cannibals[1], "Left"}})
+ table.insert(startDialogue, {func = AnimWait, args = {cannibals[1], 1000}})
+ table.insert(startDialogue, {func = AnimTurn, args = {cannibals[1], "Right"}})
+ table.insert(startDialogue, {func = AnimSay, args = {cannibals[1], loc("I can't believe it worked!"), SAY_THINK, 3500}})
+ table.insert(startDialogue, {func = AnimSay, args = {cannibals[1], loc("That shaman sure knows what he's doing!"), SAY_THINK, 6000}})
+ table.insert(startDialogue, {func = AnimSay, args = {cannibals[1], loc("Yeah...I think it's a 'he', lol."), SAY_THINK, 5000}})
+ table.insert(startDialogue, {func = AnimSay, args = {leaks, loc("It wants our brains!"), SAY_SHOUT, 3000}})
+ table.insert(startDialogue, {func = AnimTurn, args = {cannibals[1], "Left"}})
+ table.insert(startDialogue, {func = AnimSay, args = {cannibals[1], loc("Not you again! My head still hurts from last time!"), SAY_SHOUT, 6000}})
+ table.insert(startDialogue, {func = AnimSwitchHog, args = {leaks}})
+ AddSkipFunction(startDialogue, StartSkipFunc, {})
+
+ table.insert(weaklingsAnim, {func = AnimGearWait, args = {leaks, 1000}})
+ table.insert(weaklingsAnim, {func = AnimCustomFunction, args = {leaks, CondNeedToTurn, {leaks, dense}}})
+ table.insert(weaklingsAnim, {func = AnimSay, args = {leaks, loc("Did you see him coming?"), SAY_SAY, 3500}})
+ table.insert(weaklingsAnim, {func = AnimSay, args = {dense, loc("No. Where did he come from?"), SAY_SAY, 3500}})
+ table.insert(weaklingsAnim, {func = AnimCustomFunction, args = {leaks, UnHideWeaklings, {}}})
+ table.insert(weaklingsAnim, {func = AnimOutOfNowhere, args = {cannibals[2], unpack(cannibalPos[2])}})
+ table.insert(weaklingsAnim, {func = AnimGiveState, args = {cannibals[2], 0}})
+ table.insert(weaklingsAnim, {func = AnimWait, args = {leaks, 400}})
+ table.insert(weaklingsAnim, {func = AnimGiveState, args = {cannibals[3], 0}})
+ table.insert(weaklingsAnim, {func = AnimOutOfNowhere, args = {cannibals[3], unpack(cannibalPos[3])}})
+ table.insert(weaklingsAnim, {func = AnimWait, args = {leaks, 400}})
+ table.insert(weaklingsAnim, {func = AnimGiveState, args = {cannibals[4], 0}})
+ table.insert(weaklingsAnim, {func = AnimOutOfNowhere, args = {cannibals[4], unpack(cannibalPos[4])}})
+ table.insert(weaklingsAnim, {func = AnimWait, args = {leaks, 400}})
+ table.insert(weaklingsAnim, {func = AnimGiveState, args = {cannibals[5], 0}})
+ table.insert(weaklingsAnim, {func = AnimOutOfNowhere, args = {cannibals[5], unpack(cannibalPos[5])}})
+ table.insert(weaklingsAnim, {func = AnimWait, args = {leaks, 400}})
+ table.insert(weaklingsAnim, {func = AnimSay, args = {cannibals[3], loc("Are we there yet?"), SAY_SAY, 4000}})
+ table.insert(weaklingsAnim, {func = AnimSay, args = {dense, loc("This must be some kind of sorcery!"), SAY_SHOUT, 3500}})
+ table.insert(weaklingsAnim, {func = AnimSwitchHog, args = {leaks}})
+ AddSkipFunction(weaklingsAnim, SkipWeaklingsAnim, {})
+
+ table.insert(stronglingsAnim, {func = AnimGearWait, args = {leaks, 1000}})
+ table.insert(stronglingsAnim, {func = AnimCustomFunction, args = {leaks, UnHideStronglings, {}}})
+ table.insert(stronglingsAnim, {func = AnimCustomFunction, args = {leaks, CondNeedToTurn, {leaks, dense}}})
+ table.insert(stronglingsAnim, {func = AnimGiveState, args = {leaks, 0}})
+ table.insert(stronglingsAnim, {func = AnimGiveState, args = {dense, 0}})
+ table.insert(stronglingsAnim, {func = AnimSay, args = {leaks, loc("I thought their shaman died when he tried our medicine!"), SAY_SAY, 7000}})
+ table.insert(stronglingsAnim, {func = AnimSay, args = {dense, loc("I saw it with my own eyes!"), SAY_SAY, 4000}})
+ table.insert(stronglingsAnim, {func = AnimSay, args = {leaks, loc("Then how do they keep appearing?"), SAY_SAY, 4000}})
+ table.insert(stronglingsAnim, {func = AnimSay, args = {leaks, loc("It's impossible to communicate with the spirits without a shaman."), SAY_SAY, 7000}})
+ table.insert(stronglingsAnim, {func = AnimSay, args = {dense, loc("We need to warn the village."), SAY_SAY, 3500}})
+ table.insert(stronglingsAnim, {func = AnimGiveState, args = {cannibals[6], 0}})
+ table.insert(stronglingsAnim, {func = AnimOutOfNowhere, args = {cannibals[6], unpack(cannibalPos[6])}})
+ table.insert(stronglingsAnim, {func = AnimWait, args = {leaks, 400}})
+ table.insert(stronglingsAnim, {func = AnimGiveState, args = {cannibals[7], 0}})
+ table.insert(stronglingsAnim, {func = AnimOutOfNowhere, args = {cannibals[7], unpack(cannibalPos[7])}})
+ table.insert(stronglingsAnim, {func = AnimWait, args = {leaks, 400}})
+ table.insert(stronglingsAnim, {func = AnimGiveState, args = {cannibals[8], 0}})
+ table.insert(stronglingsAnim, {func = AnimOutOfNowhere, args = {cannibals[8], unpack(cannibalPos[8])}})
+ table.insert(stronglingsAnim, {func = AnimWait, args = {leaks, 400}})
+ table.insert(stronglingsAnim, {func = AnimGiveState, args = {cannibals[9], 0}})
+ table.insert(stronglingsAnim, {func = AnimOutOfNowhere, args = {cannibals[9], unpack(cannibalPos[9])}})
+ table.insert(stronglingsAnim, {func = AnimWait, args = {leaks, 400}})
+ table.insert(stronglingsAnim, {func = AnimSay, args = {cannibals[7], loc("What a ride!"), SAY_SHOUT, 2000}})
+ table.insert(stronglingsAnim, {func = AnimTurn, args = {leaks, "Right"}})
+ table.insert(stronglingsAnim, {func = AnimWait, args = {leaks, 700}})
+ table.insert(stronglingsAnim, {func = AnimTurn, args = {leaks, "Left"}})
+ table.insert(stronglingsAnim, {func = AnimSay, args = {leaks, loc("We can't defeat them!"), SAY_THINK, 3000}})
+ table.insert(stronglingsAnim, {func = AnimSay, args = {leaks, loc("I'll hold them off while you return to the village!"), SAY_SAY, 6000}})
+ table.insert(stronglingsAnim, {func = AnimFollowGear, args = {cyborg}, swh = false})
+ table.insert(stronglingsAnim, {func = AnimCaption, args = {cyborg, loc("30 minutes later...")}, swh = false})
+ table.insert(stronglingsAnim, {func = AnimWait, args = {cyborg, 2000}})
+ table.insert(stronglingsAnim, {func = AnimSetGearPosition, args = {dense, 1420, 1315}})
+ table.insert(stronglingsAnim, {func = AnimMove, args = {dense, "Left", 1400, 0}})
+ table.insert(stronglingsAnim, {func = AnimCustomFunction, args = {dense, EmitDenseClouds, {stronglingsAnim, "Left"}}})
+ table.insert(stronglingsAnim, {func = AnimMove, args = {dense, "Left", 1350, 0}})
+ table.insert(stronglingsAnim, {func = AnimOutOfNowhere, args = {cyborg, 1250, 1320}})
+ table.insert(stronglingsAnim, {func = AnimRemoveState, args = {cyborg, gstInvisible}})
+ table.insert(stronglingsAnim, {func = AnimGearWait, args = {cyborg, 2000}})
+ table.insert(stronglingsAnim, {func = AnimSay, args = {cyborg, loc("Greetings, cloudy one!"), SAY_SAY, 3000}})
+ table.insert(stronglingsAnim, {func = AnimSay, args = {cyborg, loc("I have come to make you an offering..."), SAY_SAY, 6000}})
+ table.insert(stronglingsAnim, {func = AnimSay, args = {cyborg, loc("You are given the chance to turn your life around..."), SAY_SAY, 6000}})
+ table.insert(stronglingsAnim, {func = AnimSay, args = {cyborg, loc("If you agree to provide the information we need, you will be spared!"), SAY_SAY, 7000}})
+ table.insert(stronglingsAnim, {func = AnimSay, args = {cyborg, loc("Have no illusions, your tribe is dead, indifferent of your choice."), SAY_SAY, 7000}})
+ table.insert(stronglingsAnim, {func = AnimSay, args = {cyborg, loc("If you decide to help us, though, we will no longer need to find a new governor for the island."), SAY_SAY, 8000}})
+ table.insert(stronglingsAnim, {func = AnimSay, args = {cyborg, loc("If you know what I mean..."), SAY_SAY, 3000}})
+ table.insert(stronglingsAnim, {func = AnimSay, args = {cyborg, loc("So? What will it be?"), SAY_SAY, 3000}})
+ table.insert(stronglingsAnim, {func = AnimSwitchHog, args = {dense}})
+ AddSkipFunction(stronglingsAnim, SkipStronglingsAnim, {})
+
+ table.insert(acceptedAnim, {func = AnimSay, args = {cyborg, loc("Great choice, Steve! Mind if I call you that?"), SAY_SAY, 7000}})
+ table.insert(acceptedAnim, {func = AnimSay, args = {dense, loc("Whatever floats your boat..."), SAY_SAY, 4500}})
+ table.insert(acceptedAnim, {func = AnimSay, args = {cyborg, loc("Great! You will be contacted soon for assistance."), SAY_SAY, 6000}})
+ table.insert(acceptedAnim, {func = AnimSay, args = {cyborg, loc("In the meantime, take these and return to your \"friend\"!"), SAY_SAY, 6000}})
+ table.insert(acceptedAnim, {func = AnimGiveState, args = {cyborg, gstInvisible}})
+ table.insert(acceptedAnim, {func = AnimDisappear, args = {cyborg, unpack(cyborgPos)}})
+ table.insert(acceptedAnim, {func = AnimSwitchHog, args = {dense}})
+ AddSkipFunction(acceptedAnim, SkipAcceptedAnim, {})
+
+ table.insert(acceptedDiedFinalAnim, {func = AnimSay, args = {leaks, loc("Pfew! That was close!"), SAY_THINK, 3000}})
+ table.insert(acceptedDiedFinalAnim, {func = AnimSay, args = {leaks, loc("Your death will not be in vain, Dense Cloud!"), SAY_THINK, 5000}})
+ table.insert(acceptedDiedFinalAnim, {func = AnimSay, args = {dense, loc("You will be avenged!"), SAY_SAY, 3000}})
+
+ table.insert(refusedAnim, {func = AnimSay, args = {cyborg, loc("I see..."), SAY_SAY, 2000}})
+ table.insert(refusedAnim, {func = AnimSay, args = {cyborg, loc("Remember this, pathetic animal: when the day comes, you will regret your blind loyalty!"), SAY_SAY, 8000}})
+ table.insert(refusedAnim, {func = AnimSay, args = {cyborg, loc("You just committed suicide..."), SAY_SAY, 5000}})
+ table.insert(refusedAnim, {func = AnimDisappear, args = {cyborg, unpack(cyborgPos)}})
+ table.insert(refusedAnim, {func = AnimGiveState, args = {cyborg, gstInvisible}})
+ table.insert(refusedAnim, {func = AnimSay, args = {dense, loc("If you say so..."), SAY_THINK, 3000}})
+ table.insert(refusedAnim, {func = AnimFollowGear, args = {cyborg}, swh = false})
+ table.insert(refusedAnim, {func = AnimWait, args = {cyborg, 700}})
+ table.insert(refusedAnim, {func = AnimCustomFunction, args = {dense, RefusedStart, {}}})
+ table.insert(refusedAnim, {func = AnimOutOfNowhere, args = {dense, 2645, 1146}})
+ table.insert(refusedAnim, {func = AnimOutOfNowhere, args = {ramon, 2218, 1675}})
+ table.insert(refusedAnim, {func = AnimOutOfNowhere, args = {spiky, 2400, 1675}})
+ table.insert(refusedAnim, {func = AnimTurn, args = {spiky, "Left"}})
+ table.insert(refusedAnim, {func = AnimWait, args = {cyborg, 1700}})
+ table.insert(refusedAnim, {func = AnimTurn, args = {spiky, "Right"}})
+ table.insert(refusedAnim, {func = AnimWait, args = {cyborg, 1700}})
+ table.insert(refusedAnim, {func = AnimTurn, args = {spiky, "Left"}})
+ table.insert(refusedAnim, {func = AnimSay, args = {spiky, loc("Dude, we really need a new shaman..."), SAY_SAY, 4000}})
+ AddSkipFunction(refusedAnim, SkipRefusedAnim, {})
+
+ table.insert(refusedFinalAnim, {func = AnimSay, args = {leaks, loc("It's over..."), SAY_SAY, 2000}})
+ table.insert(refusedFinalAnim, {func = AnimSay, args = {leaks, loc("Let's head back to the village!"), SAY_SAY, 4000}})
+
+ table.insert(attackedAnim, {func = AnimCustomFunction, args = {dense, CondNeedToTurn, {cyborg, dense}}})
+ table.insert(attackedAnim, {func = AnimCustomFunction, args = {cyborg, SetHealth, {cyborg, 200}}})
+ table.insert(attackedAnim, {func = AnimWait, args = {cyborg, 2000}})
+ table.insert(attackedAnim, {func = AnimSay, args = {cyborg, loc("Really?! You thought you could harm me with your little toys?"), SAY_SAY, 7000}})
+ table.insert(attackedAnim, {func = AnimSay, args = {cyborg, loc("You're pathetic! You are not worthy of my attention..."), SAY_SAY, 6000}})
+ table.insert(attackedAnim, {func = AnimSay, args = {cyborg, loc("Actually, you aren't worthy of life! Take this..."), SAY_SAY, 5000}})
+ table.insert(attackedAnim, {func = AnimCustomFunction, args = {dense, BlowDenseCloud, {}}, swh = false})
+ table.insert(attackedAnim, {func = AnimWait, args = {cyborg, 2000}})
+ table.insert(attackedAnim, {func = AnimSay, args = {cyborg, loc("Incredible..."), SAY_SAY, 3000}})
+ table.insert(attackedAnim, {func = AnimDisappear, args = {cyborg, unpack(cyborgPos)}})
+ table.insert(attackedAnim, {func = AnimGiveState, args = {cyborg, gstInvisible}})
+ table.insert(attackedAnim, {func = AnimSwitchHog, args = {leaks}})
+ table.insert(attackedAnim, {func = AnimSay, args = {leaks, loc("I wonder where Dense Cloud is..."), SAY_THINK, 4000}})
+ table.insert(attackedAnim, {func = AnimSay, args = {leaks, loc("I can't wait any more, I have to save myself!"), SAY_THINK, 5000}})
+ table.insert(attackedAnim, {func = AnimCustomFunction, args = {leaks, SpawnCrates, {}}})
+ table.insert(attackedAnim, {func = AnimWait, args = {leaks, 1500}})
+ table.insert(attackedAnim, {func = AnimSay, args = {leaks, loc("Where are all these crates coming from?!"), SAY_THINK, 5500}})
+ AddSkipFunction(attackedAnim, SkipAttackedAnim, {})
+
+ table.insert(attackedFinalAnim, {func = AnimWait, args = {leaks, 2000}})
+ table.insert(attackedFinalAnim, {func = AnimSay, args = {leaks, loc("I have to get back to the village!"), SAY_THINK, 5000}})
+ table.insert(attackedFinalAnim, {func = AnimSay, args = {leaks, loc("Dense Cloud must have already told them everything..."), SAY_THINK, 7000}})
+
+end
+
+
+-----------------------------Misc--------------------------------------
+
+
+function RefusedStart()
+ if ramonHidden == true then
+ RestoreHog(ramon)
+ ramonHidden = false
+ end
+ if spikyHidden == true then
+ RestoreHog(spiky)
+ spikyHidden = false
+ end
+ SetState(ramon, 0)
+ SetState(spiky, 0)
+ SetGearMessage(dense, 0)
+ SetGearMessage(ramon, 0)
+ SetGearMessage(spiky, 0)
+end
+
+function AddHogs()
+ AddTeam(loc("Natives"), 29439, "Bone", "Island", "HillBilly", "cm_birdy")
+ ramon = AddHog(loc("Ramon"), 0, 100, "rasta")
+ leaks = AddHog(loc("Leaks A Lot"), 0, 100, "Rambo")
+ dense = AddHog(loc("Dense Cloud"), 0, 100, "RobinHood")
+ spiky = AddHog(loc("Spiky Cheese"), 0, 100, "hair_yellow")
+
+ AddTeam(loc("Weaklings"), 14483456, "Skull", "Island", "Pirate","cm_vampire")
+ cannibals = {}
+ cannibals[1] = AddHog(loc("Brainiac"), 5, 20, "Zombi")
+
+ for i = 2, 5 do
+ cannibals[i] = AddHog(HogNames[i], 1, 20, "Zombi")
+ hogNr[cannibals[i]] = i - 2
+ end
+
+ AddTeam(loc("Stronglings"), 14483456, "Skull", "Island", "Pirate","cm_vampire")
+
+ for i = 6, 9 do
+ cannibals[i] = AddHog(HogNames[i], 2, 30, "vampirichog")
+ hogNr[cannibals[i]] = i - 2
+ end
+
+ AddTeam(loc("011101001"), 14483456, "ring", "UFO", "Robot", "cm_star")
+ cyborg = AddHog(loc("Y3K1337"), 0, 200, "cyborg1")
+end
+
+function PlaceHogs()
+ HogTurnLeft(leaks, true)
+
+ for i = 2, 9 do
+ AnimSetGearPosition(cannibals[i], unpack(cyborgPos))
+ AnimTurn(cannibals[i], "Left")
+ cannibalDead[i] = false
+ end
+
+ AnimSetGearPosition(cannibals[1], cannibalPos[1][1], cannibalPos[1][2])
+ AnimTurn(cannibals[1], "Left")
+
+ AnimSetGearPosition(cyborg, cyborgPos[1], cyborgPos[2])
+ AnimSetGearPosition(ramon, 2218, 1675)
+ AnimSetGearPosition(skiky, 2400, 1675)
+ AnimSetGearPosition(dense, densePos[1], densePos[2])
+ AnimSetGearPosition(leaks, leaksPos[1], leaksPos[2])
+end
+
+function VisiblizeHogs()
+ for i = 1, 9 do
+ SetState(cannibals[i], gstInvisible)
+ end
+ SetState(cyborg, gstInvisible)
+ SetState(ramon, gstInvisible)
+ SetState(spiky, gstInvisible)
+end
+
+function CondNeedToTurn(hog1, hog2)
+ xl, xd = GetX(hog1), GetX(hog2)
+ if xl > xd then
+ AnimInsertStepNext({func = AnimTurn, args = {hog1, "Left"}})
+ AnimInsertStepNext({func = AnimTurn, args = {hog2, "Right"}})
+ elseif xl < xd then
+ AnimInsertStepNext({func = AnimTurn, args = {hog2, "Left"}})
+ AnimInsertStepNext({func = AnimTurn, args = {hog1, "Right"}})
+ end
+end
+
+function HideHogs()
+ for i = 2, 9 do
+ HideHog(cannibals[i])
+ isHidden[cannibals[i]] = true
+ end
+ HideHog(cyborg)
+ cyborgHidden = true
+ HideHog(ramon)
+ HideHog(spiky)
+ ramonHidden = true
+ spikyHidden = true
+end
+
+function HideStronglings()
+ for i = 6, 9 do
+ HideHog(cannibals[i])
+ isHidden[cannibals[i]] = true
+ end
+end
+
+function UnHideWeaklings()
+ for i = 2, 5 do
+ RestoreHog(cannibals[i])
+ isHidden[cannibals[i]] = false
+ SetState(cannibals[i], gstInvisible)
+ end
+end
+
+function UnHideStronglings()
+ for i = 6, 9 do
+ RestoreHog(cannibals[i])
+ isHidden[cannibals[i]] = false
+ SetState(cannibals[i], gstInvisible)
+ end
+ RestoreHog(cyborg)
+ cyborgHidden = false
+ SetState(cyborg, gstInvisible)
+end
+
+function ChoiceTaken()
+ SetGearMessage(CurrentHedgehog, 0)
+ if choice == choiceAccept then
+ AddAnim(acceptedAnim)
+ AddFunction({func = AfterAcceptedAnim, args = {}})
+ elseif choice == choiceRefuse then
+ AddAnim(refusedAnim)
+ AddFunction({func = AfterRefusedAnim, args = {}})
+ else
+ AddAnim(attackedAnim)
+ AddFunction({func = AfterAttackedAnim, args = {}})
+ end
+end
+
+function KillCyborg()
+ RestoreHog(cyborg)
+ DeleteGear(cyborg)
+ TurnTimeLeft = 0
+end
+-----------------------------Events------------------------------------
+
+function CheckBrainiacDead()
+ return brainiacDead
+end
+
+function DoBrainiacDead()
+ TurnTimeLeft = 0
+ SetGearMessage(CurrentHedgehog, 0)
+ AddAnim(weaklingsAnim)
+ AddFunction({func = AfterWeaklingsAnim, args = {}})
+ stage = interSpyStage
+end
+
+function CheckWeaklingsKilled()
+ for i = 2, 5 do
+ if cannibalDead[i] == false then
+ return false
+ end
+ end
+ return true
+end
+
+function DoWeaklingsKilled()
+ SetGearMessage(CurrentHedgehog, 0)
+ AddAnim(stronglingsAnim)
+ AddFunction({func = AfterStronglingsAnim, args = {}})
+ stage = interWeakStage
+ ParseCommand("teamgone " .. loc("Weaklings"))
+end
+
+function CheckRefuse()
+ return GetX(dense) > 1400 and StoppedGear(dense)
+end
+
+function DoRefuse()
+ choice = choiceRefuse
+end
+
+function CheckAccept()
+ return GetX(dense) < 1300 and StoppedGear(dense)
+end
+
+function DoAccept()
+ choice = choiceAccept
+end
+
+function CheckConfront()
+ return cyborgAttacked and StoppedGear(dense)
+end
+
+function DoConfront()
+ choice = choiceAttack
+end
+
+function CheckChoice()
+ return choice ~= 0
+end
+
+function DoChoice()
+ RemoveEventFunc(CheckConfront)
+ RemoveEventFunc(CheckAccept)
+ RemoveEventFunc(CheckRefuse)
+ ChoiceTaken()
+end
+
+function CheckNeedGirder()
+ return GetX(dense) > 1640 and StoppedGear(dense)
+end
+
+function DoNeedGirder()
+ ShowMission(loc("The Shadow Falls"), loc("Under Construction"), loc("To place a girder, select it, use [Left] and [Right] to select angle and length, place with [Left Click]"), 1, 6000)
+end
+
+function CheckNeedWeapons()
+ return GetX(dense) > 2522 and StoppedGear(dense)
+end
+
+function DoNeedWeapons()
+ grenadeCrate = SpawnAmmoCrate(2550, 800, amGrenade)
+ shotgunCrate = SpawnAmmoCrate(2610, 850, amShotgun)
+ AddCaption(loc("A little gift from the cyborgs"))
+end
+
+function CheckTookWeapons()
+ return shotgunTaken and grenadeTaken
+end
+
+function DoTookWeapons()
+ ShowMission(loc("The Shadow Falls"), loc("The guardian"), loc("Protect yourselves!|Grenade hint: set the timer with [1-5], aim with [Up]/[Down] and hold [Space] to set power"), 1, 8000)
+ AddAmmo(dense, amSkip, 100)
+ AddAmmo(dense, amSwitch, 100)
+ AddAmmo(leaks, amSkip, 100)
+ AddAmmo(leaks, amSwitch, 100)
+ stage = duoStage
+ RemoveEventFunc(CheckNeedGirder)
+ RemoveEventFunc(CheckNeedWeapons)
+ RemoveEventFunc(CheckRestartReturnAccepted)
+ AddEvent(CheckStronglingsDead, {}, DoStronglingsDead, {}, 0)
+ AddAmmo(cannibals[6], amGrenade, 2)
+ AddAmmo(cannibals[6], amShotgun, 2)
+ AddAmmo(cannibals[7], amGrenade, 2)
+ AddAmmo(cannibals[7], amShotgun, 2)
+ AddAmmo(cannibals[8], amGrenade, 2)
+ AddAmmo(cannibals[8], amShotgun, 2)
+ AddAmmo(cannibals[9], amGrenade, 2)
+ AddAmmo(cannibals[9], amShotgun, 2)
+ SetGearMessage(leaks, 0)
+ SetGearMessage(dense, 0)
+ TurnTimeLeft = TurnTime
+end
+
+function DoStronglingsDead()
+ SetGearMessage(CurrentHedgehog, 0)
+ if denseDead == true then
+ AddAnim(acceptedDiedFinalAnim)
+ SaveCampaignVar("M2DenseDead", "1")
+ else
+ SetupAcceptedSurvivedFinalAnim()
+ AddAnim(acceptedSurvivedFinalAnim)
+ SaveCampaignVar("M2DenseDead", "0")
+ end
+ SaveCampaignVar("M2RamonDead", "0")
+ SaveCampaignVar("M2SpikyDead", "0")
+ AddFunction({func = KillCyborg, args = {}})
+ if progress and progress<2 then
+ SaveCampaignVar("Progress", "2")
+ end
+ SaveCampaignVar("M2Choice", "" .. choice)
+end
+
+function DoStronglingsDeadRefused()
+ if denseDead == true then
+ SaveCampaignVar("M2DenseDead", "1")
+ else
+ SaveCampaignVar("M2DenseDead", "0")
+ end
+ if ramonDead == true then
+ SaveCampaignVar("M2RamonDead", "1")
+ else
+ SaveCampaignVar("M2RamonDead", "0")
+ end
+ if spikyDead == true then
+ SaveCampaignVar("M2SpikyDead", "1")
+ else
+ SaveCampaignVar("M2SpikyDead", "0")
+ end
+ AddAnim(refusedFinalAnim)
+ AddFunction({func = KillCyborg, args = {}})
+ if progress and progress<2 then
+ SaveCampaignVar("Progress", "2")
+ end
+ SaveCampaignVar("M2Choice", "" .. choice)
+end
+
+function DoStronglingsDeadAttacked()
+ SaveCampaignVar("M2DenseDead", "1")
+ SaveCampaignVar("M2RamonDead", "0")
+ SaveCampaignVar("M2SpikyDead", "0")
+ if progress and progress<2 then
+ SaveCampaignVar("Progress", "2")
+ end
+ SaveCampaignVar("M2Choice", "" .. choice)
+ AddAnim(attackedFinalAnim)
+ AddFunction({func = KillCyborg, args = {}})
+end
+
+function CheckStronglingsDead()
+ if leaksDead == true then
+ return false
+ end
+ for i = 6, 9 do
+ if cannibalDead[i] == false then
+ return false
+ end
+ end
+ return true
+end
+
+function CheckLeaksDead()
+ return leaksDead
+end
+
+function DoDead()
+ AddCaption(loc("...and so the cyborgs took over the world..."))
+ stage = loseStage
+ TurnTimeLeft = 0
+ ParseCommand("teamgone " .. loc("Natives"))
+end
+
+function CheckDenseDead()
+ return denseDead and choice ~= choiceAttack
+end
+
+function CheckRestartReturnAccepted()
+ return retryReturn
+end
+
+-----------------------------Main Functions----------------------------
+
+function onGameInit()
+ Seed = 334
+ GameFlags = gfSolidLand + gfDisableWind + gfPerHogAmmo
+ TurnTime = 50000
+ CaseFreq = 0
+ MinesNum = 0
+ MinesTime = 3000
+ Explosives = 0
+ Delay = 10
+ Map = "A_Classic_Fairytale_shadow"
+ Theme = "Nature"
+ SuddenDeathTurns = 3000
+
+ AddHogs()
+ PlaceHogs()
+ VisiblizeHogs()
+
+ AnimInit()
+ AnimationSetup()
+end
+
+function onGameStart()
+ progress = tonumber(GetCampaignVar("Progress"))
+ HideHogs()
+ AddAmmo(leaks, amSwitch, 100)
+ AddAmmo(dense, amSwitch, 100)
+ AddEvent(CheckLeaksDead, {}, DoDead, {}, 0)
+ AddEvent(CheckDenseDead, {}, DoDead, {}, 0)
+ AddAnim(startDialogue)
+ AddFunction({func = AfterStartDialogue, args = {}})
+ AddEvent(CheckBrainiacDead, {}, DoBrainiacDead, {}, 0)
+ ShowMission(loc("The Shadow Falls"), loc("The First Encounter"), loc("Survive!|Hint: Cinematics can be skipped with the [Precise] key."), 1, 0)
+end
+
+function onGameTick()
+ AnimUnWait()
+ if ShowAnimation() == false then
+ return
+ end
+ ExecuteAfterAnimations()
+ CheckEvents()
+end
+
+function onGearDelete(gear)
+ if gear == cannibals[1] then
+ brainiacDead = true
+ elseif gear == grenadeCrate then
+ grenadeTaken = true
+ elseif gear == shotgunCrate then
+ shotgunTaken = true
+ elseif gear == dense then
+ denseDead = true
+ elseif gear == leaks then
+ leaksDead = true
+ elseif gear == ramon then
+ ramonDead = true
+ elseif gear == spiky then
+ spikyDead = true
+ else
+ for i = 2, 9 do
+ if gear == cannibals[i] then
+ cannibalDead[i] = true
+ end
+ end
+ end
+end
+
+function onGearAdd(gear)
+ if GetGearType(gear) == gtGrenade and GetHogTeamName(CurrentHedgehog) == loc("Natives") then
+ grenadeUsed = true
+ elseif GetGearType(gear) == gtShotgunShot and GetHogTeamName(CurrentHedgehog) == loc("Natives") then
+ shotgunUsed = true
+ end
+end
+
+function onAmmoStoreInit()
+ SetAmmo(amDEagle, 9, 0, 0, 0)
+ SetAmmo(amSniperRifle, 6, 0, 0, 0)
+ SetAmmo(amFirePunch, 3, 0, 0, 0)
+ SetAmmo(amWhip, 4, 0, 0, 0)
+ SetAmmo(amBaseballBat, 4, 0, 0, 0)
+ SetAmmo(amHammer, 2, 0, 0, 0)
+ SetAmmo(amLandGun, 1, 0, 0, 0)
+ SetAmmo(amSnowball, 7, 0, 0, 0)
+ SetAmmo(amGirder, 0, 0, 0, 2)
+ SetAmmo(amParachute, 0, 0, 0, 2)
+ SetAmmo(amGrenade, 0, 0, 0, 3)
+ SetAmmo(amShotgun, 0, 0, 0, 3)
+ SetAmmo(amSwitch, 0, 0, 0, 8)
+ SetAmmo(amRope, 0, 0, 0, 6)
+end
+
+function onNewTurn()
+ if AnimInProgress() then
+ TurnTimeLeft = -1
+-- elseif stage == interSpyStage and GetHogTeamName(CurrentHedgehog) ~= loc("Natives") then
+-- TurnTimeLeft = 0
+-- SetState(CurrentHedgehog, gstInvisible)
+ elseif stage == cyborgStage then
+ if CurrentHedgehog ~= dense then
+ TurnTimeLeft = 0
+ else
+ TurnTimeLeft = -1
+ end
+ elseif stage == acceptedReturnStage then
+ SwitchHog(dense)
+ FollowGear(dense)
+ TurnTimeLeft = -1
+ end
+end
+
+function onGearDamage(gear, damage)
+ if gear == cyborg and stage == cyborgStage then
+ cyborgAttacked = true
+ end
+end
+
+function onPrecise()
+ if GameTime > 2500 and AnimInProgress() then
+ SetAnimSkip(true)
+ return
+ end
+ if stage == acceptedReturnStage then
+ retryReturn = true
+-- else
+-- for i = 1, 9 do
+-- DeleteGear(cannibals[i])
+-- end
+ end
+end
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Missions/Campaign/A_Classic_Fairytale/united.lua Mon Jul 01 23:23:22 2013 +0300
@@ -0,0 +1,524 @@
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Animate.lua")
+
+-----------------------------Constants---------------------------------
+choiceAccept = 1
+choiceRefuse = 2
+choiceAttack = 3
+
+leaksPos = {2067, 509}
+densePos = {1882, 503}
+waterPos = {3100, 930}
+buffaloPos = {2609, 494}
+chiefPos = {2538, 617}
+cannibalPos = {{2219, 1339}, {2322, 1357}, {805, 784}, {3876, 1048},
+ {1101, 916}, {2854, 1408}, {1974, 486}, {1103, 961}}
+
+HogNames = {loc("Olive"), loc("Brain Stu"), loc("Brainila"), loc("Salivaslurper"),
+ loc("Spleenlover"), loc("Thighlicker"), loc("NomNom"), loc("Mindy")}
+
+natives = {}
+-----------------------------Variables---------------------------------
+cannibals = {}
+cannibalDead = {}
+cannibalHidden = {}
+cratesSpawned = {}
+healthCratesSpawned = {}
+
+sdrmv = 0
+denseDead = false
+leaksDead = false
+waterDead = false
+buffaloDead = false
+chiefDead = false
+nativesDead = {}
+
+m2Choice = 0
+m2DenseDead = 0
+
+startAnim = {}
+wave2Anim = {}
+finalAnim = {}
+--------------------------Anim skip functions--------------------------
+function AfterHogDeadAnim()
+ freshDead = nil
+ TurnTimeLeft = TurnTime
+end
+
+function AfterStartAnim()
+ local goal = loc("Defeat the cannibals!|")
+ local chiefgoal = loc("Try to protect the chief! You won't lose if he dies, but it is advised that he survives.")
+ TurnTimeLeft = TurnTime
+ ShowMission(loc("United We Stand"), loc("Invasion"), goal .. chiefgoal, 1, 6000)
+end
+
+function SkipStartAnim()
+ AnimSetGearPosition(water, 2467, 754)
+ if cratesSpawned[1] ~= true then
+ SpawnCrates(1)
+ end
+ if healthCratesSpawned[1] ~= true then
+ SpawnHealthCrates(1)
+ end
+ if cannibalHidden[1] == true then
+ RestoreWave(1)
+ end
+ AnimSwitchHog(leaks)
+end
+
+function SkipWave2Anim()
+ if cratesSpawned[2] ~= true then
+ SpawnCrates(2)
+ end
+ if healthCratesSpawned[2] ~= true then
+ SpawnHealthCrates(2)
+ end
+ if cannibalHidden[5] == true then
+ RestoreWave(2)
+ end
+ AnimSwitchHog(cannibals[5])
+end
+
+function AfterWave2Anim()
+ TurnTimeLeft = 0
+end
+
+function AfterFinalAnim()
+ if leaksDead == true then
+ SaveCampaignVar("M4LeaksDead", "1")
+ else
+ SaveCampaignVar("M4LeaksDead", "0")
+ end
+ if chiefDead == true then
+ SaveCampaignVar("M4ChiefDead", "1")
+ else
+ SaveCampaignVar("M4ChiefDead", "0")
+ end
+ if buffaloDead == true then
+ SaveCampaignVar("M4BuffaloDead", "1")
+ else
+ SaveCampaignVar("M4BuffaloDead", "0")
+ end
+ if waterDead == true then
+ SaveCampaignVar("M4WaterDead", "1")
+ else
+ SaveCampaignVar("M4WaterDead", "0")
+ end
+ if denseDead == true then
+ SaveCampaignVar("M4DenseDead", "1")
+ else
+ SaveCampaignVar("M4DenseDead", "0")
+ end
+ if progress and progress<4 then
+ SaveCampaignVar("Progress", "4")
+ end
+ ParseCommand("teamgone " .. loc("011101001"))
+ TurnTimeLeft = 0
+end
+-----------------------------Animations--------------------------------
+function Wave2Reaction()
+ local i = 1
+ local gearr = nil
+ while nativesDead[i] == true do
+ i = i + 1
+ end
+ gearr = natives[i]
+ if denseDead ~= true and band(GetState(dense), gstDrowning) == 0 then
+ AnimInsertStepNext({func = AnimSay, args = {dense, loc("I'm so scared!"), SAY_SAY, 3000}})
+ AnimInsertStepNext({func = AnimCustomFunction, args = {dense, EmitDenseClouds, {"Left"}}})
+ AnimInsertStepNext({func = AnimTurn, args = {dense, "Left"}})
+ end
+ AnimInsertStepNext({func = AnimSay, args = {gearr, loc("There's more of them? When did they become so hungry?"), SAY_SHOUT, 8000}})
+end
+
+function EmitDenseClouds(dir)
+ local dif
+ if dir == "Left" then
+ dif = 10
+ else
+ dif = -10
+ end
+ AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
+ AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
+ AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
+ AnimInsertStepNext({func = AnimWait, args = {dense, 800}})
+ AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
+ AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
+ AnimInsertStepNext({func = AnimWait, args = {dense, 800}})
+ AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false})
+end
+
+function AnimationSetup()
+ table.insert(startAnim, {func = AnimWait, args = {leaks, 4000}})
+ table.insert(startAnim, {func = AnimCaption, args = {leaks, loc("Back in the village, after telling the villagers about the threat..."), 5000}})
+ table.insert(startAnim, {func = AnimCaption, args = {leaks, loc("Their buildings were very primitive back then, even for an uncivilised island."), 7000}})
+ table.insert(startAnim, {func = AnimSay, args = {chief, loc("Young one, you are telling us that they can instantly change location without a shaman?"), SAY_SAY, 8000}})
+ table.insert(startAnim, {func = AnimSay, args = {chief, loc("That is, indeed, very weird..."), SAY_SAY, 3500}})
+ table.insert(startAnim, {func = AnimSay, args = {buffalo, loc("If they try coming here, they can have a taste of my delicious knuckles!"), SAY_SHOUT, 8000}})
+ table.insert(startAnim, {func = AnimSay, args = {buffalo, loc("Haha!"), SAY_SHOUT, 2000}})
+ if denseDead == false then
+ table.insert(startAnim, {func = AnimSay, args = {dense, loc("I'm not sure about that!"), SAY_SAY, 3400}})
+ table.insert(startAnim, {func = AnimSay, args = {dense, loc("They have weapons we've never seen before!"), SAY_SAY, 5000}})
+ table.insert(startAnim, {func = AnimSay, args = {dense, loc("Luckily, I've managed to snatch some of them."), SAY_SAY, 5000}})
+ table.insert(startAnim, {func = AnimCustomFunction, args = {dense, SpawnCrates, {1}}})
+ table.insert(startAnim, {func = AnimSay, args = {dense, loc("Oops...I dropped them."), SAY_SAY, 3000}})
+ else
+ table.insert(startAnim, {func = AnimSay, args = {leaks, loc("I'm not sure about that!"), SAY_SAY, 3400}})
+ table.insert(startAnim, {func = AnimSay, args = {leaks, loc("They have weapons we've never seen before!"), SAY_SAY, 5000}})
+ table.insert(startAnim, {func = AnimCustomFunction, args = {leaks, SpawnCrates, {1}}})
+ table.insert(startAnim, {func = AnimWait, args = {leaks, 1000}})
+ table.insert(startAnim, {func = AnimSay, args = {leaks, loc("They keep appearing like this. It's weird!"), SAY_SAY, 5000}})
+ end
+ table.insert(startAnim, {func = AnimSay, args = {chief, loc("Did anyone follow you?"), SAY_SAY, 3000}})
+ table.insert(startAnim, {func = AnimSay, args = {leaks, loc("No, we made sure of that!"), SAY_SAY, 3500}})
+ table.insert(startAnim, {func = AnimCustomFunction, args = {leaks, SpawnHealthCrates, {1}}})
+ table.insert(startAnim, {func = AnimWait, args = {leaks, 1000}})
+ table.insert(startAnim, {func = AnimSay, args = {chief, loc("First aid kits?!"), SAY_SAY, 3000}})
+ table.insert(startAnim, {func = AnimSay, args = {leaks, loc("I've seen this before. They just appear out of thin air."), SAY_SAY, 7000}})
+ table.insert(startAnim, {func = AnimMove, args = {water, "Left", 3000, 0}})
+ table.insert(startAnim, {func = AnimJump, args = {water, "long"}})
+ table.insert(startAnim, {func = AnimMove, args = {water, "Left", 2655, 0}})
+ table.insert(startAnim, {func = AnimTurn, args = {water, "Right"}})
+ table.insert(startAnim, {func = AnimJump, args = {water, "back"}})
+ table.insert(startAnim, {func = AnimJump, args = {water, "back"}})
+ table.insert(startAnim, {func = AnimTurn, args = {water, "Left"}})
+ table.insert(startAnim, {func = AnimMove, args = {water, "Left", 2467, 754}})
+ table.insert(startAnim, {func = AnimSay, args = {water, loc("Hey guys!"), SAY_SAY, 2500}})
+ table.insert(startAnim, {func = AnimSay, args = {chief, loc("..."), SAY_THINK, 1500}})
+ table.insert(startAnim, {func = AnimSay, args = {chief, loc("Where have you been?"), SAY_SAY, 4000}})
+ table.insert(startAnim, {func = AnimSay, args = {water, loc("Just on a walk."), SAY_SAY, 3000}})
+ table.insert(startAnim, {func = AnimSay, args = {chief, loc("You have chosen the perfect moment to leave."), SAY_SAY, 6000}})
+ table.insert(startAnim, {func = AnimCustomFunction, args = {chief, RestoreWave, {1}}})
+ for i = 1, 4 do
+ table.insert(startAnim, {func = AnimOutOfNowhere, args = {cannibals[i], unpack(cannibalPos[i])}})
+ end
+ table.insert(startAnim, {func = AnimWait, args = {chief, 1500}})
+ table.insert(startAnim, {func = AnimSay, args = {leaks, loc("HOW DO THEY KNOW WHERE WE ARE???"), SAY_SHOUT, 5000}})
+ table.insert(startAnim, {func = AnimSay, args = {chief, loc("We have to protect the village!"), SAY_SAY, 5000}})
+ table.insert(startAnim, {func = AnimSwitchHog, args = {leaks}})
+ AddSkipFunction(startAnim, SkipStartAnim, {})
+
+ table.insert(wave2Anim, {func = AnimCustomFunction, args = {leaks, RestoreWave, {2}}, swh = false})
+ for i = 5, 8 do
+ table.insert(wave2Anim, {func = AnimOutOfNowhere, args = {cannibals[i], unpack(cannibalPos[i])}})
+ end
+ table.insert(wave2Anim, {func = AnimCustomFunction, args = {leaks, Wave2Reaction, {}}, swh = false})
+ table.insert(wave2Anim, {func = AnimCustomFunction, args = {leaks, SpawnCrates, {2}}, swh = false})
+ table.insert(wave2Anim, {func = AnimCustomFunction, args = {leaks, SpawnHealthCrates, {2}}, swh = false})
+ table.insert(wave2Anim, {func = AnimSwitchHog, args = {cannibals[5]}})
+ AddSkipFunction(wave2Anim, SkipWave2Anim, {})
+end
+
+function SetupHogDeadAnim(gear)
+ hogDeadAnim = {}
+ if nativesNum == 0 then
+ return
+ end
+ local hogDeadStrings = {loc("They killed ") .. gear ..loc("! You bastards!"),
+ gear .. loc("! Why?!"),
+ loc("That was just mean!"),
+ loc("Oh no, not ") .. gear .. "!"}
+ table.insert(hogDeadAnim, {func = AnimSay, args = {CurrentHedgehog, hogDeadStrings[nativesNum], SAY_SHOUT, 4000}})
+end
+
+function SetupFinalAnim()
+ local found = 0
+ local hogs = {}
+ local i = 1
+ if nativesNum >= 2 then
+ while found < 2 do
+ if nativesDead[i] ~= true then
+ found = found + 1
+ hogs[found] = natives[i]
+ end
+ i = i + 1
+ end
+ if chiefDead ~= true then
+ hogs[2] = chief
+ end
+ table.insert(finalAnim, {func = AnimCustomFunction, args = {hogs[1], CondNeedToTurn, {hogs[1], hogs[2]}}})
+ table.insert(finalAnim, {func = AnimSay, args = {hogs[1], loc("We can't hold them up much longer!"), SAY_SAY, 5000}})
+ table.insert(finalAnim, {func = AnimSay, args = {hogs[1], loc("We need to move!"), SAY_SAY, 3000}})
+ table.insert(finalAnim, {func = AnimSay, args = {hogs[2], loc("But where can we go?"), SAY_SAY, 3000}})
+ table.insert(finalAnim, {func = AnimSay, args = {hogs[1], loc("To the caves..."), SAY_SAY, 2500}})
+ table.insert(finalAnim, {func = AnimSay, args = {hogs[2], loc("Good idea, they'll never find us there!"), SAY_SAY, 5000}})
+ else
+ for i = 1, 5 do
+ if nativesDead[i] ~= true then
+ hogs[1] = natives[i]
+ end
+ end
+ table.insert(finalAnim, {func = AnimSay, args = {hogs[1], loc("I need to move the tribe!"), SAY_THINK, 4000}})
+ table.insert(finalAnim, {func = AnimSay, args = {hogs[1], loc("The caves are well hidden, they won't find us there!"), SAY_THINK, 7000}})
+ end
+end
+-----------------------------Misc--------------------------------------
+function RestoreWave(index)
+ for i = (index - 1) * 4 + 1, index * 4 do
+ RestoreHog(cannibals[i])
+ cannibalHidden[i] = false
+ end
+end
+
+function GetVariables()
+ m2DenseDead = tonumber(GetCampaignVar("M2DenseDead"))
+ if m2DenseDead == 1 then
+ denseDead = true
+ end
+ m2Choice = tonumber(GetCampaignVar("M2Choice"))
+end
+
+function SetupPlace()
+ if m2DenseDead == 1 then
+ sdrmv = 1
+ DeleteGear(dense)
+ end
+ for i = 1, 8 do
+ HideHog(cannibals[i])
+ cannibalHidden[i] = true
+ end
+ HideHog(cyborg)
+end
+
+function SetupEvents()
+ AddEvent(CheckWaveDead, {1}, DoWaveDead, {1}, 0)
+ AddEvent(CheckWaveDead, {2}, DoWaveDead, {2}, 0)
+end
+
+function SetupAmmo()
+ AddAmmo(cannibals[1], amGrenade, 4)
+ AddAmmo(cannibals[1], amBazooka, 4)
+ AddAmmo(cannibals[1], amShotgun, 4)
+ AddAmmo(cannibals[1], amMine, 2)
+ AddAmmo(cannibals[5], amGrenade, 4)
+ AddAmmo(cannibals[5], amBazooka, 4)
+ AddAmmo(cannibals[5], amShotgun, 4)
+ AddAmmo(cannibals[5], amMine, 2)
+ AddAmmo(cannibals[5], amMolotov, 2)
+ AddAmmo(cannibals[5], amFlamethrower, 3)
+end
+
+function AddHogs()
+ AddTeam(loc("Natives"), 29439, "Bone", "Island", "HillBilly", "cm_birdy")
+ leaks = AddHog(loc("Leaks A Lot"), 0, 100, "Rambo")
+ dense = AddHog(loc("Dense Cloud"), 0, 100, "RobinHood")
+ water = AddHog(loc("Fiery Water"), 0, 100, "pirate_jack")
+ buffalo = AddHog(loc("Raging Buffalo"), 0, 100, "zoo_Bunny")
+ chief = AddHog(loc("Righteous Beard"), 0, 100, "IndianChief")
+ natives = {leaks, dense, water, buffalo, chief}
+ nativesNum = 5
+
+ AddTeam(loc("Light Cannfantry"), 14483456, "Skull", "Island", "Pirate", "cm_vampire")
+ for i = 1, 4 do
+ cannibals[i] = AddHog(HogNames[i], 2, 40, "Zombi")
+ end
+
+ AddTeam(loc("Heavy Cannfantry"), 14483456, "Skull", "Island", "Pirate", "cm_vampire")
+ for i = 5, 8 do
+ cannibals[i] = AddHog(HogNames[i], 2, 55, "vampirichog")
+ end
+
+ AddTeam(loc("011101001"), 14483456, "ring", "UFO", "Robot", "cm_star")
+ cyborg = AddHog(loc("Unit 334a$7%;.*"), 0, 200, "cyborg1")
+
+ AnimSetGearPosition(leaks, unpack(leaksPos))
+ AnimSetGearPosition(dense, unpack(densePos))
+ AnimSetGearPosition(water, unpack(waterPos))
+ HogTurnLeft(water, true)
+ AnimSetGearPosition(buffalo, unpack(buffaloPos))
+ HogTurnLeft(buffalo, true)
+ AnimSetGearPosition(chief, unpack(chiefPos))
+ HogTurnLeft(chief, true)
+ AnimSetGearPosition(cyborg, 0, 0)
+ for i = 1, 8 do
+ AnimSetGearPosition(cannibals[i], unpack(cannibalPos[i]))
+ end
+end
+
+function CondNeedToTurn(hog1, hog2)
+ xl, xd = GetX(hog1), GetX(hog2)
+ if xl > xd then
+ AnimInsertStepNext({func = AnimTurn, args = {hog1, "Left"}})
+ AnimInsertStepNext({func = AnimTurn, args = {hog2, "Right"}})
+ elseif xl < xd then
+ AnimInsertStepNext({func = AnimTurn, args = {hog2, "Left"}})
+ AnimInsertStepNext({func = AnimTurn, args = {hog1, "Right"}})
+ end
+end
+
+function SpawnHealthCrates(index)
+ SetHealth(SpawnHealthCrate(0, 0), 25)
+ SetHealth(SpawnHealthCrate(0, 0), 25)
+ SetHealth(SpawnHealthCrate(0, 0), 25)
+ healthCratesSpawned[index] = true
+end
+
+function SpawnCrates(index)
+ if index == 1 then
+ SpawnAmmoCrate(1943, 408, amBazooka)
+ SpawnAmmoCrate(1981, 464, amGrenade)
+ SpawnAmmoCrate(1957, 459, amShotgun)
+ SpawnAmmoCrate(1902, 450, amDynamite)
+ SpawnUtilityCrate(1982, 405, amPickHammer)
+ SpawnUtilityCrate(2028, 455, amRope)
+ SpawnUtilityCrate(2025, 464, amTeleport)
+ else
+ SpawnUtilityCrate(1982, 405, amBlowTorch)
+ SpawnAmmoCrate(2171, 428, amMolotov)
+ SpawnAmmoCrate(2364, 346, amFlamethrower)
+ SpawnAmmoCrate(2521, 303, amBazooka)
+ SpawnAmmoCrate(2223, 967, amGrenade)
+ SpawnAmmoCrate(1437, 371, amShotgun)
+ end
+ cratesSpawned[index] = true
+end
+
+-----------------------------Events------------------------------------
+
+function CheckWaveDead(index)
+ for i = (index - 1) * 4 + 1, index * 4 do
+ if cannibalDead[i] ~= true then
+ return false
+ end
+ end
+ return true
+end
+
+function DoWaveDead(index)
+ SetGearMessage(CurrentHedgehog, 0)
+ SetState(CurrentHedgehog, 0)
+ if index == 1 then
+ AddAnim(wave2Anim)
+ AddFunction({func = AfterWave2Anim, args = {}})
+ elseif index == 2 then
+ SetupFinalAnim()
+ AddAnim(finalAnim)
+ AddFunction({func = AfterFinalAnim, args = {}})
+ end
+end
+
+
+-----------------------------Main Functions----------------------------
+
+function onGameInit()
+ Seed = 1
+ GameFlags = 0
+ TurnTime = 60000
+ CaseFreq = 0
+ MinesNum = 0
+ MinesTime = 3000
+ Explosives = 2
+ Delay = 10
+ Map = "Hogville"
+ Theme = "Nature"
+ SuddenDeathTurns = 3000
+
+ AddHogs()
+ AnimInit()
+end
+
+function onGameStart()
+ progress = tonumber(GetCampaignVar("Progress"))
+ GetVariables()
+ SetupAmmo()
+ SetupPlace()
+ AnimationSetup()
+ SetupEvents()
+ AddAnim(startAnim)
+ AddFunction({func = AfterStartAnim, args = {}})
+end
+
+function onGameTick()
+ AnimUnWait()
+ if ShowAnimation() == false then
+ return
+ end
+ ExecuteAfterAnimations()
+ CheckEvents()
+end
+
+function onGearDelete(gear)
+ if gear == dense then
+ denseDead = true
+ nativesNum = nativesNum - 1
+ nativesDead[2] = true
+ if sdrmv == 1 then
+ freshDead = nil
+ else
+ freshDead = loc("Dense Cloud")
+ end
+ elseif gear == leaks then
+ leaksDead = true
+ nativesNum = nativesNum - 1
+ nativesDead[1] = true
+ freshDead = loc("Leaks A Lot")
+ elseif gear == chief then
+ chiefDead = true
+ nativesNum = nativesNum - 1
+ nativesDead[5] = true
+ freshDead = loc("Righteous Beard")
+ elseif gear == water then
+ waterDead = true
+ nativesNum = nativesNum - 1
+ nativesDead[3] = true
+ freshDead = loc("Fiery Water")
+ elseif gear == buffalo then
+ buffaloDead = true
+ nativesNum = nativesNum - 1
+ nativesDead[4] = true
+ freshDead = loc("Raging Buffalo")
+ else
+ for i = 1, 8 do
+ if gear == cannibals[i] then
+ cannibalDead[i] = true
+ end
+ end
+ end
+end
+
+function onAmmoStoreInit()
+ SetAmmo(amDEagle, 9, 0, 0, 0)
+ SetAmmo(amSniperRifle, 4, 0, 0, 0)
+ SetAmmo(amFirePunch, 9, 0, 0, 0)
+ SetAmmo(amWhip, 9, 0, 0, 0)
+ SetAmmo(amBaseballBat, 9, 0, 0, 0)
+ SetAmmo(amHammer, 9, 0, 0, 0)
+ SetAmmo(amLandGun, 9, 0, 0, 0)
+ SetAmmo(amSnowball, 8, 0, 0, 0)
+ SetAmmo(amGirder, 4, 0, 0, 2)
+ SetAmmo(amParachute, 4, 0, 0, 2)
+ SetAmmo(amSwitch, 8, 0, 0, 2)
+ SetAmmo(amSkip, 8, 0, 0, 0)
+ SetAmmo(amRope, 5, 0, 0, 3)
+ SetAmmo(amBlowTorch, 3, 0, 0, 3)
+ SetAmmo(amPickHammer, 0, 0, 0, 3)
+ SetAmmo(amLowGravity, 0, 0, 0, 2)
+ SetAmmo(amDynamite, 0, 0, 0, 3)
+ SetAmmo(amBazooka, 0, 0, 0, 4)
+ SetAmmo(amGrenade, 0, 0, 0, 5)
+ SetAmmo(amMine, 0, 0, 0, 2)
+ SetAmmo(amMolotov, 0, 0, 0, 3)
+ SetAmmo(amFlamethrower, 0, 0, 0, 3)
+ SetAmmo(amShotgun, 0, 0, 0, 3)
+ SetAmmo(amTeleport, 0, 0, 0, 2)
+ SetAmmo(amFlamethrower, 0, 0, 0, 3)
+end
+
+function onNewTurn()
+ if AnimInProgress() then
+ TurnTimeLeft = -1
+ return
+ end
+ if freshDead ~= nil and GetHogTeamName(CurrentHedgehog) == loc("Natives") then
+ SetupHogDeadAnim(freshDead)
+ AddAnim(hogDeadAnim)
+ AddFunction({func = AfterHogDeadAnim, args = {}})
+ end
+end
+
+function onPrecise()
+ if GameTime > 2500 then
+ SetAnimSkip(true)
+ end
+end
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/CMakeLists.txt Mon Jul 01 23:23:22 2013 +0300
@@ -0,0 +1,9 @@
+file(GLOB Config *.ini)
+file(GLOB Missions *.lua)
+file(GLOB Packs *.hwp)
+
+install(FILES
+ ${Config}
+ ${Missions}
+ ${Packs}
+ DESTINATION "${SHAREPATH}Data/Missions/Campaign/A_Space_Adventure")
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/campaign.ini Mon Jul 01 23:23:22 2013 +0300
@@ -0,0 +1,22 @@
+MissionNum=5
+ResetRetry=1
+
+[Mission 1]
+Name=The Spacetrip
+Script=cosmos.lua
+
+[Mission 2]
+Name=Moon:The First Stop
+Script=moon01.lua
+
+[Mission 3]
+Name=FRUIT
+Script=fruit.lua
+
+[Mission 4]
+Name=DESERT
+Script=desert.lua
+
+[Mission 5]
+Name=ICE
+Script=ice.lua
Binary file share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/cosmos.hwp has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/cosmos.lua Mon Jul 01 23:23:22 2013 +0300
@@ -0,0 +1,390 @@
+------------------- ABOUT ----------------------
+--
+-- This map works as a menu for the hero hog to
+-- navigate through planets. It portrays the hogs
+-- planet and above the planets that he'll later
+-- visit.
+
+-- TODO
+-- Save and Load All Check Points
+-- Save hero health
+-- Decide and implement if hero will use gas bombs...
+-- ofc add custom stats page
+-- PROBLEM : What if one makes a bad choice and wants to replay it map, how to reset?
+-- POSSIBLE SOLUTIONS: In game function keys, frontend button...
+
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Animate.lua")
+
+----------------- VARIABLES --------------------
+-- globals
+local campaignName = loc("A Space Adventure")
+local missionName = loc("Cosmos")
+local timeForGuard1ToTurn = 1000 * 5 -- 5 sec
+local timeForGuard1ToTurnLeft = timeForGuard1ToTurn
+local saucerAcquired = false
+local checkPointReached = 1 -- 1 is start of the game
+-- dialogs
+local dialog01 = {}
+local dialog02 = {}
+local dialog03 = {}
+local dialog04 = {}
+local dialog05 = {}
+local dialog06 = {}
+-- mission objectives
+local goals = {
+ [dialog01] = {missionName, loc("Getting ready"), loc("Go and collect the crate on top of the column").."|"..loc("Use the sleep gas bomb if the guards spot you!"), 1, 4500},
+ [dialog02] = {missionName, loc("The adventure begins!"), loc("Use the saucer and fly to the moon").."|"..loc("Drive carefully as your fuels are limited"), 1, 4500},
+ [dialog03] = {missionName, loc("An unexpected event!"), loc("Use the saucer and fly away or use the gas bomb to neutralize the guards").."|"..loc("Beware, any damage taken will stay until you take some medicine or visit moon"), 1, 7000}
+}
+-- crates
+local saucerX = 3270
+local saucerY = 1500
+-- hogs
+local hero = {}
+local director = {}
+local doctor = {}
+local guard1 = {}
+local guard2 = {}
+-- teams
+local teamA = {}
+local teamB = {}
+local teamC = {}
+-- hedgehogs values
+hero.name = loc("Hog Solo")
+hero.x = 1450
+hero.y = 1550
+director.name = loc("H")
+director.x = 1350
+director.y = 1550
+doctor.name = loc("Dr.Cornelius")
+doctor.x = 1300
+doctor.y = 1550
+guard1.name = loc("Bob")
+guard1.x = 3350
+guard1.y = 1800
+guard1.turn = false
+guard1.keepTurning = true
+guard2.name = loc("Sam")
+guard2.x = 3400
+guard2.y = 1800
+teamA.name = loc("PAoTH")
+teamA.color = tonumber("FF0000",16) -- red
+teamB.name = loc("Guards")
+teamB.color = tonumber("0033FF",16) -- blue
+teamC.name = loc("Hog Solo")
+teamC.color = tonumber("38D61C",16) -- green
+
+-------------- LuaAPI EVENT HANDLERS ------------------
+function onGameInit()
+ Seed = 35
+ GameFlags = gfSolidLand + gfDisableWind
+ TurnTime = 40000
+ CaseFreq = 0
+ MinesNum = 0
+ Explosives = 0
+ Delay = 5
+ Map = "cosmos_map" -- custom map included in file
+ Theme = "Nature"
+ -- I had originally hero in PAoTH team and changed it, may reconsider though
+ -- PAoTH
+ AddTeam(teamC.name, teamC.color, "Bone", "Island", "HillBilly", "cm_birdy")
+ hero.gear = AddHog(hero.name, 0, 100, "war_desertgrenadier1")
+ AnimSetGearPosition(hero.gear, hero.x, hero.y)
+ HogTurnLeft(hero.gear, true)
+ AddTeam(teamA.name, teamA.color, "Bone", "Island", "HillBilly", "cm_birdy")
+ director.gear = AddHog(director.name, 0, 100, "hair_yellow")
+ AnimSetGearPosition(director.gear, director.x, director.y)
+ doctor.gear = AddHog(doctor.name, 0, 100, "Glasses")
+ AnimSetGearPosition(doctor.gear, doctor.x, doctor.y)
+ -- Guards
+ AddTeam(teamB.name, teamB.color, "Bone", "Island", "HillBilly", "cm_birdy")
+ guard1.gear = AddHog(guard1.name, 1, 100, "policecap")
+ AnimSetGearPosition(guard1.gear, guard1.x, guard1.y)
+ guard2.gear = AddHog(guard2.name, 1, 100, "policecap")
+ AnimSetGearPosition(guard2.gear, guard2.x, guard2.y)
+
+ -- get the check point
+ if tonumber(GetCampaignVar("CosmosCheckPoint")) then
+ checkPointReached = tonumber(GetCampaignVar("CosmosCheckPoint"))
+ end
+ -- do checkpoint stuff needed before game starts
+ if checkPointReached == 1 then
+ -- Start of the game
+ elseif checkPointReached == 2 then
+ -- Hero on the column, just took space ship unnoticed
+ AnimSetGearPosition(hero.gear, saucerX, saucerY)
+ elseif checkPointReached == 3 then
+ -- Hero near column, without space ship unnoticed
+ elseif checkPointReached == 4 then
+ -- Hero visited moon for fuels
+ AnimSetGearPosition(hero.gear, 1110, 850)
+ elseif checkPointReached == 5 then
+ -- Hero has visited a planet, he has plenty of fuels and can change planet
+ end
+
+ AnimInit()
+ AnimationSetup()
+end
+
+function onGameStart()
+ -- wait for the first turn to start
+ AnimWait(hero.gear, 3000)
+
+ FollowGear(hero.gear)
+ ShowMission(loc("A Space Adventure"), loc("Cosmos"), loc("Help Hog Solo to find all the parts of the anti-gravity device.")..
+ "|"..loc("Travel to all the neighbor planets and collect all the pieces"), -amSkip, 0)
+
+ -- do checkpoint stuff needed after game starts
+ if checkPointReached == 1 then
+ AddAnim(dialog01)
+ AddAmmo(hero.gear, amGasBomb, 5)
+ AddAmmo(hero.gear, amRope, 2)
+ -- Added for dev/debug purposes, remove before release
+ AddAmmo(hero.gear, amJetpack, 2)
+ AddAmmo(guard1.gear, amDEagle, 2)
+ AddAmmo(guard2.gear, amDEagle, 2)
+ SpawnAmmoCrate(saucerX, saucerY, amJetpack)
+ -- EVENT HANDLERS
+ AddEvent(onHeroBeforeTreePosition, {hero.gear}, heroBeforeTreePosition, {hero.gear}, 0)
+ AddEvent(onHeroAtSaucerPosition, {hero.gear}, heroAtSaucerPosition, {hero.gear}, 0)
+ AddEvent(onHeroOutOfGuardSight, {hero.gear}, heroOutOfGuardSight, {hero.gear}, 0)
+ elseif checkPointReached == 2 then
+ AddAmmo(hero.gear, amJetpack, 1)
+ AddAnim(dialog02)
+ elseif checkPointReached == 3 then
+ -- Hero near column, without space ship unnoticed
+ elseif checkPointReached == 4 then
+ -- Hero visited moon for fuels
+ AddAnim(dialog05)
+ elseif checkPointReached == 5 then
+ -- Hero has visited a planet, he has plenty of fuels and can change planet
+ end
+ -- always check for landings
+ if GetCampaignVar("Planet") ~= "moon" then
+ AddEvent(onMoonLanding, {hero.gear}, moonLanding, {hero.gear}, 0)
+ end
+ if GetCampaignVar("Planet") ~= "desertPlanet" then
+ AddEvent(onDesertPlanetLanding, {hero.gear}, desertPlanetLanding, {hero.gear}, 0)
+ end
+ if GetCampaignVar("Planet") ~= "fruitPlanet" then
+ AddEvent(onFruitPlanetLanding, {hero.gear}, fruitPlanetLanding, {hero.gear}, 0)
+ end
+ if GetCampaignVar("Planet") ~= "icePlanet" then
+ AddEvent(onIcePlanetLanding, {hero.gear}, icePlanetLanding, {hero.gear}, 0)
+ end
+end
+
+function onGameTick()
+ -- maybe alert this to avoid timeForGuard1ToTurnLeft overflow
+ if timeForGuard1ToTurnLeft == 0 and guard1.keepTurning then
+ guard1.turn = not guard1.turn
+ HogTurnLeft(guard1.gear, guard1.turn)
+ timeForGuard1ToTurnLeft = timeForGuard1ToTurn
+ end
+ timeForGuard1ToTurnLeft = timeForGuard1ToTurnLeft - 1
+ AnimUnWait()
+ if ShowAnimation() == false then
+ return
+ end
+ ExecuteAfterAnimations()
+ CheckEvents()
+end
+
+function onPrecise()
+ if GameTime > 3000 then
+ SetAnimSkip(true)
+ end
+end
+
+function onAmmoStoreInit()
+ SetAmmo(amJetpack, 0, 0, 0, 1)
+end
+
+function onNewTurn()
+ if CurrentHedgehog == director.gear or CurrentHedgehog == doctor.gear then
+ TurnTimeLeft = 0
+ end
+ if guard1.keepTurning then
+ AnimSwitchHog(hero.gear)
+ TurnTimeLeft = -1
+ end
+end
+
+-------------- EVENTS ------------------
+
+function onHeroBeforeTreePosition(gear)
+ if GetX(gear) > 2444 then
+ return true
+ end
+ return false
+end
+
+function onHeroAtSaucerPosition(gear)
+ if GetX(gear) >= saucerX-32 and GetX(gear) <= saucerX+32 and GetY(gear) >= saucerY-32 and GetY(gear) <= saucerY+32 then
+ saucerAcquired = true
+ end
+ if saucerAcquired and StoppedGear(gear) then
+ return true
+ end
+ return false
+end
+
+function onHeroOutOfGuardSight(gear)
+ if GetX(gear) < 3100 and GetY(gear) > saucerY-25 and StoppedGear(gear) and not guard1.keepTurning then
+ return true
+ end
+ return false
+end
+--
+function onMoonLanding(gear)
+ if GetX(gear) > 1010 and GetX(gear) < 1220 and GetY(gear) < 1300 and StoppedGear(gear) then
+ return true
+ end
+ return false
+end
+
+function onFruitPlanetLanding(gear)
+ if GetX(gear) > 2240 and GetX(gear) < 2540 and GetY(gear) < 1100 and StoppedGear(gear) then
+ return true
+ end
+ return false
+end
+
+function onDesertPlanetLanding(gear)
+ if GetX(gear) > 3568 and GetX(gear) < 4052 and GetY(gear) < 500 and StoppedGear(gear) then
+ return true
+ end
+ return false
+end
+
+function onIcePlanetLanding(gear)
+ if GetX(gear) > 1330 and GetX(gear) < 1650 and GetY(gear) < 500 and StoppedGear(gear) then
+ return true
+ end
+ return false
+end
+
+-------------- OUTCOMES ------------------
+
+function heroBeforeTreePosition(gear)
+ AnimSay(gear,loc("Now I have to climb the trees"), SAY_SAY, 4000)
+ AnimCaption(hero.gear, loc("Use the rope to get to the crate"), 4000)
+end
+
+function heroAtSaucerPosition(gear)
+ TurnTimeLeft = 0
+ -- save check point
+ SaveCampaignVar("CosmosCheckPoint", "2")
+ AddAnim(dialog02)
+ -- check if he was spotted by the guard
+ if guard1.turn then
+ guard1.keepTurning = false
+ AddAnim(dialog03)
+ end
+end
+
+function heroOutOfGuardSight(gear)
+ guard1.keepTurning = true
+ AddAnim(dialog04)
+end
+
+function moonLanding(gear)
+ WriteLnToConsole("MOON LANDING, HOORAY!")
+ AnimCaption(hero.gear,loc("Welcome to the moon!"))
+ SaveCampaignVar("CosmosCheckPoint", "4")
+ SaveCampaignVar("Planet", "moon")
+ EndGame()
+end
+
+function fruitPlanetLanding(gear)
+ if checkPointReached < 5 then
+ AddAnim(dialog06)
+ end
+end
+
+function desertPlanetLanding(gear)
+ if checkPointReached < 5 then
+ AddAnim(dialog06)
+ end
+end
+
+function icePlanetLanding(gear)
+ if checkPointReached < 5 then
+ AddAnim(dialog06)
+ end
+end
+
+-------------- ANIMATIONS ------------------
+
+function Skipanim(anim)
+ if goals[anim] ~= nil then
+ ShowMission(unpack(goals[anim]))
+ end
+ if CurrentHedgehog ~= hero.gear and anim ~= dialog03 then
+ AnimSwitchHog(hero.gear)
+ elseif anim == dialog03 then
+ startCombat()
+ elseif anim == dialog05 or anim == dialog06 then
+ EndGame()
+ end
+end
+
+function AnimationSetup()
+ -- DIALOG 01 - Start
+ AddSkipFunction(dialog01, Skipanim, {dialog01})
+ table.insert(dialog01, {func = AnimWait, args = {doctor.gear, 3000}})
+ --table.insert(dialog01, {func = AnimWait, args = {hero.gear, 2500}, skipFunc = Skipanim, skipArgs = dialog01})
+ table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("Near secret base 17 of PAoTH in the rural Hogland..."), 4000}})
+ table.insert(dialog01, {func = AnimSay, args = {director.gear, loc("So Hog Solo, here we are..."), SAY_SAY, 2000}})
+ table.insert(dialog01, {func = AnimSay, args = {director.gear, loc("Behind these trees on the East there is secret base 17"), SAY_SAY, 4000}})
+ table.insert(dialog01, {func = AnimSay, args = {director.gear, loc("You have to continue alone from now on."), SAY_SAY, 3000}})
+ table.insert(dialog01, {func = AnimSay, args = {director.gear, loc("Be careful, the future of Hogera is in your hands!"), SAY_SAY, 7200}})
+ table.insert(dialog01, {func = AnimSay, args = {doctor.gear, loc("We'll use our communicators to contact you"), SAY_SAY, 2600}})
+ table.insert(dialog01, {func = AnimSay, args = {doctor.gear, loc("In am also entrusting you with a rope and a sleep gas bomb"), SAY_SAY, 5000}})
+ table.insert(dialog01, {func = AnimSay, args = {doctor.gear, loc("You may find them handy"), SAY_SAY, 2300}})
+ table.insert(dialog01, {func = AnimSay, args = {hero.gear, loc("Thank you Dr.Cornelius"), SAY_SAY, 1600}})
+ table.insert(dialog01, {func = AnimSay, args = {hero.gear, loc("I'll make good use of them"), SAY_SAY, 4500}})
+ table.insert(dialog01, {func = AnimSay, args = {director.gear, loc("It would be wiser to steal the space ship while PAoTH guards are taking a brake!"), SAY_SAY, 7000}})
+ table.insert(dialog01, {func = AnimSay, args = {director.gear, loc("Remember! Many will seek the anti-gravity device! Now go, hurry up!"), SAY_SAY, 4000}})
+ table.insert(dialog01, {func = AnimSwitchHog, args = {hero.gear}})
+ -- DIALOG 02 - Hero got the saucer
+ AddSkipFunction(dialog02, Skipanim, {dialog02})
+ table.insert(dialog02, {func = AnimWait, args = {hero.gear, 500}})
+ table.insert(dialog02, {func = AnimCaption, args = {hero.gear, loc("CheckPoint reached!"), 4000}})
+ table.insert(dialog02, {func = AnimSay, args = {hero.gear, loc("Got the saucer!"), SAY_SHOUT, 2000}})
+ table.insert(dialog02, {func = AnimSay, args = {director.gear, loc("Nice!"), SAY_SHOUT, 1000}})
+ table.insert(dialog02, {func = AnimSay, args = {director.gear, loc("Now use it and go to the moon PAoTH station to get more fuels!"), SAY_SHOUT, 5000}})
+ table.insert(dialog02, {func = AnimGearWait, args = {hero.gear, 500}})
+ -- DIALOG 03 - Hero got spotted by guard
+ AddSkipFunction(dialog03, Skipanim, {dialog03})
+ table.insert(dialog03, {func = AnimWait, args = {guard1.gear, 4000}})
+ table.insert(dialog03, {func = AnimCaption, args = {guard1.gear, loc("Prepare to battle or flee!"), 4000}})
+ table.insert(dialog03, {func = AnimSay, args = {guard1.gear, loc("Hey").." "..guard2.name.."! "..loc("Look, someone is stealing the saucer!"), SAY_SHOUT, 4000}})
+ table.insert(dialog03, {func = AnimSay, args = {guard2.gear, loc("I'll get him!"), SAY_SAY, 4000}})
+ table.insert(dialog03, {func = startCombat, args = {guard1.gear}})
+ -- DIALOG 04 - Hero out of sight
+ AddSkipFunction(dialog04, Skipanim, {dialog04})
+ table.insert(dialog04, {func = AnimCaption, args = {guard1.gear, loc("You are out of danger, time to go to the moon!"), 4000}})
+ table.insert(dialog04, {func = AnimSay, args = {guard1.gear, loc("I guess we lost him!"), SAY_SAY, 3000}})
+ table.insert(dialog04, {func = AnimSay, args = {guard2.gear, loc("We should better report this and continue our watch!"), SAY_SAY, 5000}})
+ table.insert(dialog04, {func = AnimSwitchHog, args = {hero.gear}})
+ -- DIALOG 05 - Hero returned from moon without fuels
+ AddSkipFunction(dialog05, Skipanim, {dialog05})
+ table.insert(dialog05, {func = AnimSay, args = {hero.gear, loc("I guess I can't go far without fuels!"), SAY_THINK, 6000}})
+ table.insert(dialog05, {func = AnimSay, args = {hero.gear, loc("Go to go back"), SAY_THINK, 2000}})
+ table.insert(dialog05, {func = EndGame, args = {hero.gear}})
+ -- DIALOG 06 - Landing on wrong planet or on earth if not enough fuels
+ AddSkipFunction(dialog06, Skipanim, {dialog06})
+ table.insert(dialog06, {func = AnimCaption, args = {hero.gear, loc("You have to try again!"), 5000}})
+ table.insert(dialog06, {func = AnimSay, args = {hero.gear, loc("Hm... Now I run out of fuels..."), SAY_THINK, 3000}})
+ table.insert(dialog06, {func = EndGame, args = {hero.gear}})
+end
+
+------------------- custom "animation" functions --------------------------
+
+function startCombat()
+ -- use this so guard2 will gain control
+ AnimSwitchHog(hero.gear)
+ TurnTimeLeft = 0
+end
--- a/share/hedgewars/Data/Missions/Campaign/CMakeLists.txt Mon Jul 01 22:28:42 2013 +0300
+++ b/share/hedgewars/Data/Missions/Campaign/CMakeLists.txt Mon Jul 01 23:23:22 2013 +0300
@@ -1,5 +1,5 @@
-add_subdirectory("A Classic Fairytale")
-add_subdirectory("A Space Adventure")
+add_subdirectory("A_Classic_Fairytale")
+add_subdirectory("A_Space_Adventure")
file(GLOB Scripts *.lua)
--- a/share/hedgewars/Data/Scripts/Multiplayer/ShoppaMap.lua Mon Jul 01 22:28:42 2013 +0300
+++ b/share/hedgewars/Data/Scripts/Multiplayer/ShoppaMap.lua Mon Jul 01 23:23:22 2013 +0300
@@ -31,7 +31,9 @@
-- 700x700 for object space
function DrawStar(x, y, d, f)
-- default scale is 700x700 or so
- s = 700
+ local s = 700
+ local i = 0
+ local j = 0
if not(d == 1) then s = div(s,d) end
if NoOverlap(x,y,s,s) then
AddCollision(x,y,s,s)
@@ -158,7 +160,7 @@
end
function DrawCrescent(x, y, w, s)
- b = div(w*(GetRandom(4)+1)*10+6,6)
+ local b = div(w*(GetRandom(4)+1)*10+6,6)
if NoOverlap(x,y,w*10+6,w*10+6) then
AddCollision(x,y,w*10+6,w*10+6)
@@ -178,8 +180,9 @@
end
function DrawCones(x,w,h,c)
- y = 2048-h
- hw = div(w,2)
+ local i = 0
+ local y = 2048-h
+ local hw = div(w,2)
if NoOverlap(x+div(w*c,2),y+div(h,2),w*c,h) then
AddCollision(x+div(w*c,2),y+div(h,2),w*c,h)
x = x + hw
@@ -204,6 +207,10 @@
end
function DrawPlateau(x,y,l,t,b)
+ local bo = 0
+ local to = 0
+ local bSucc = false
+ local tSucc = false
if NoOverlapXY(x-28,y-28,x+l+28,y+l+28) then
AddPoint(x,y,5)
AddPoint(x+l,y)
@@ -299,13 +306,15 @@
h = h
x = x-div(w,2)
y = y-div(h,2)
- x2 = x+w
- y2 = y+h
- return NoOverlapXY(x,y,x2,y2)
+ return NoOverlapXY(x,y,x+w,y+h)
end
function NoOverlapXY(x,y,x2,y2)
- i=1
- l=table.getn(ObjectList)
+ local i = 1
+ local l = table.getn(ObjectList)
+ local ox = 0
+ local oy = 0
+ local ox2 = 0
+ local oy2 = 0
while i<=l do
ox = ObjectList[i][1]
oy = ObjectList[i][2]
@@ -322,8 +331,12 @@
end
function dbg()
- i=1
- l=table.getn(ObjectList)
+ local i = 1
+ local l = table.getn(ObjectList)
+ local ox = 0
+ local oy = 0
+ local ox2 = 0
+ local oy2 = 0
while i<=l do
ox = ObjectList[i][1]
oy = ObjectList[i][2]
@@ -342,8 +355,14 @@
function onGameInit()
MapGen = 2
TemplateFilter = 0
- TotGen = 0
- Tries = 0
+ local TotGen = 0
+ local Tries = 0
+ local i = 0
+ local l = 0
+ local x = 0
+ local y = 0
+ local w = 0
+ local h = 0
if band(GameFlags,gfBottomBorder) == 0 and GetRandom(2) == 0 then
AddPoint(-50,2010,7)
AddPoint(4150,2010)