Skip to content

Commit

Permalink
Make insane difficulty give 2x power income to AIs. Add qtscript func…
Browse files Browse the repository at this point in the history
…tion setPowerModifier(power[, player])

to change the power modifier from scripts. Closes ticket:3820.
  • Loading branch information
perim committed Dec 8, 2012
1 parent a173897 commit 7e18c73
Show file tree
Hide file tree
Showing 9 changed files with 62 additions and 27 deletions.
10 changes: 10 additions & 0 deletions data/base/script/rules.js
Expand Up @@ -22,6 +22,16 @@ function eventStartLevel()
{
eventStructureBuilt(structlist[i]);
}

// set income modifier for player 0 (human)
if (difficulty == EASY)
{
setPowerModifier(110);
}
else if (difficulty == HARD)
{
setPowerModifier(90);
}
}

function eventStructureBuilt(struct)
Expand Down
6 changes: 6 additions & 0 deletions data/mp/multiplay/skirmish/rules.js
Expand Up @@ -13,6 +13,12 @@ function eventGameInit()
hackNetOff();
for (var playnum = 0; playnum < maxPlayers; playnum++)
{
// insane difficulty is meant to be insane...
if (playerData[playnum].difficulty == INSANE)
{
setPowerModifier(200, playnum);
}

setDroidLimit(playnum, 150, DROID_ANY);
setDroidLimit(playnum, 10, DROID_COMMAND);
setDroidLimit(playnum, 15, DROID_CONSTRUCT);
Expand Down
14 changes: 4 additions & 10 deletions src/difficulty.cpp
Expand Up @@ -56,25 +56,19 @@ void setDifficultyLevel(DIFFICULTY_LEVEL lev)
fDifEnemyModifier = 100;
break;
case DL_HARD:
case DL_INSANE:
fDifPlayerModifier = 80;
fDifEnemyModifier = 100;
break;
case DL_KILLER:
fDifPlayerModifier = 999; // 10 times
fDifEnemyModifier = 1; // almost nothing
break;
case DL_TOUGH:
fDifPlayerModifier = 100;
fDifEnemyModifier = 50; // they do less damage!
break;
default:
debug( LOG_ERROR, "Invalid difficulty level selected - forcing NORMAL" );
fDifPlayerModifier = 100;
fDifEnemyModifier = 100;
lev = DL_NORMAL;
case DL_KILLER:
fDifPlayerModifier = 999; // 10 times
fDifEnemyModifier = 1; // almost nothing
break;
}

presDifLevel = lev;
}

Expand Down
1 change: 1 addition & 0 deletions src/difficulty.h
Expand Up @@ -26,6 +26,7 @@ enum DIFFICULTY_LEVEL
DL_EASY,
DL_NORMAL,
DL_HARD,
DL_INSANE,
DL_TOUGH,
DL_KILLER
};
Expand Down
3 changes: 2 additions & 1 deletion src/frontend.cpp
Expand Up @@ -1352,9 +1352,10 @@ bool runGameOptionsMenu(void)
case DL_HARD:
widgSetString(psWScreen,FRONTEND_DIFFICULTY_R, _("Hard") );
break;
case DL_INSANE:
case DL_TOUGH:
case DL_KILLER:
debug(LOG_ERROR, "runGameOptionsMenu: Unused difficulty level selected!");
debug(LOG_ERROR, "Unused difficulty level selected!");
break;
}
break;
Expand Down
23 changes: 8 additions & 15 deletions src/power.cpp
Expand Up @@ -46,9 +46,6 @@


#define EXTRACT_POINTS 1
#define EASY_POWER_MOD 110
#define NORMAL_POWER_MOD 100
#define HARD_POWER_MOD 90
#define MAX_POWER 1000000

#define FP_ONE ((int64_t)1 << 32)
Expand All @@ -74,10 +71,16 @@ struct PlayerPower
// All fields are 32.32 fixed point.
int64_t currentPower; ///< The current amount of power available to the player.
std::vector<PowerRequest> powerQueue; ///< Requested power.
int powerModifier; ///< Percentage modifier on power from each derrick.
};

static PlayerPower asPower[MAX_PLAYERS];

void setPowerModifier(int player, int modifier)
{
asPower[player].powerModifier = modifier;
}

/*allocate the space for the playerPower*/
bool allocPlayerPower()
{
Expand All @@ -92,6 +95,7 @@ void clearPlayerPower()
for (unsigned player = 0; player < MAX_PLAYERS; player++)
{
asPower[player].currentPower = 0;
asPower[player].powerModifier = 100;
asPower[player].powerQueue.clear();
}
}
Expand Down Expand Up @@ -213,7 +217,6 @@ void powerCalc(bool on)
static int64_t updateExtractedPower(STRUCTURE *psBuilding)
{
RES_EXTRACTOR *pResExtractor;
int modifier = NORMAL_POWER_MOD;
int64_t extractedPoints;

pResExtractor = (RES_EXTRACTOR *) psBuilding->pFunctionality;
Expand All @@ -223,18 +226,8 @@ static int64_t updateExtractedPower(STRUCTURE *psBuilding)
//and has got some power to extract
if (pResExtractor->active)
{
// Add modifier according to difficulty level
if (game.type == CAMPAIGN) // other types do not make sense
{
switch (getDifficultyLevel())
{
case DL_EASY: modifier = EASY_POWER_MOD; break;
case DL_HARD: modifier = HARD_POWER_MOD; break;
default: break;
}
}
// include modifier as a %
extractedPoints = modifier * EXTRACT_POINTS * FP_ONE / (100 * GAME_UPDATES_PER_SEC);
extractedPoints = asPower[psBuilding->player].powerModifier * EXTRACT_POINTS * FP_ONE / (100 * GAME_UPDATES_PER_SEC);
syncDebug("updateExtractedPower%d = %"PRId64"", psBuilding->player, extractedPoints);
}
ASSERT(extractedPoints >= 0, "extracted negative amount of power");
Expand Down
2 changes: 2 additions & 0 deletions src/power.h
Expand Up @@ -60,6 +60,8 @@ extern void updatePlayerPower(UDWORD player);
void setPower(unsigned player, int32_t power);
void setPrecisePower(unsigned player, int64_t power);

void setPowerModifier(int player, int modifier);

/** Get the amount of power current held by the given player. */
int32_t getPower(unsigned player);
int64_t getPrecisePower(unsigned player);
Expand Down
10 changes: 9 additions & 1 deletion src/qtscript.cpp
Expand Up @@ -41,6 +41,7 @@
#include "lib/gamelib/gtime.h"
#include "multiplay.h"
#include "map.h"
#include "difficulty.h"

#include "qtscriptfuncs.h"

Expand Down Expand Up @@ -416,7 +417,14 @@ bool loadPlayerScript(QString path, int player, int difficulty)
engine->globalObject().setProperty("gameTime", gameTime, QScriptValue::ReadOnly | QScriptValue::Undeletable);
//== \item[difficulty] The currently set campaign difficulty, or the current AI's difficulty setting. It will be one of
//== EASY, MEDIUM, HARD or INSANE.
engine->globalObject().setProperty("difficulty", difficulty, QScriptValue::ReadOnly | QScriptValue::Undeletable);
if (game.type == SKIRMISH)
{
engine->globalObject().setProperty("difficulty", difficulty, QScriptValue::ReadOnly | QScriptValue::Undeletable);
}
else // campaign
{
engine->globalObject().setProperty("difficulty", (int)getDifficultyLevel(), QScriptValue::ReadOnly | QScriptValue::Undeletable);
}
//== \item[mapName] The name of the current map.
engine->globalObject().setProperty("mapName", game.map, QScriptValue::ReadOnly | QScriptValue::Undeletable);
//== \item[baseType] The type of base that the game starts with. It will be one of CAMP_CLEAN, CAMP_BASE or CAMP_WALLS.
Expand Down
20 changes: 20 additions & 0 deletions src/qtscriptfuncs.cpp
Expand Up @@ -2215,6 +2215,25 @@ static QScriptValue js_setPower(QScriptContext *context, QScriptEngine *engine)
return QScriptValue();
}

//-- \subsection{setPowerModifier(power[, player])}
//-- Set a player's power modifier percentage. (Do not use this in an AI script.)
static QScriptValue js_setPowerModifier(QScriptContext *context, QScriptEngine *engine)
{
int power = context->argument(0).toInt32();
int player;
if (context->argumentCount() > 1)
{
player = context->argument(1).toInt32();
SCRIPT_ASSERT_PLAYER(context, player);
}
else
{
player = engine->globalObject().property("me").toInt32();
}
setPowerModifier(player, power);
return QScriptValue();
}

//-- \subsection{enableStructure(structure type[, player])}
//-- The given structure type is made available to the given player. It will appear in the
//-- player's build list.
Expand Down Expand Up @@ -3363,6 +3382,7 @@ bool registerFunctions(QScriptEngine *engine, QString scriptName)
engine->globalObject().setProperty("completeResearch", engine->newFunction(js_completeResearch));
engine->globalObject().setProperty("enableResearch", engine->newFunction(js_enableResearch));
engine->globalObject().setProperty("setPower", engine->newFunction(js_setPower));
engine->globalObject().setProperty("setPowerModifier", engine->newFunction(js_setPowerModifier));
engine->globalObject().setProperty("setTutorialMode", engine->newFunction(js_setTutorialMode));
engine->globalObject().setProperty("setDesign", engine->newFunction(js_setDesign));
engine->globalObject().setProperty("enableTemplate", engine->newFunction(js_enableTemplate));
Expand Down

0 comments on commit 7e18c73

Please sign in to comment.