File: Script.c

package info (click to toggle)
openclonk 8.1-4
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 169,520 kB
  • sloc: cpp: 180,479; ansic: 108,988; xml: 31,371; python: 1,223; php: 767; makefile: 145; sh: 101; javascript: 34
file content (173 lines) | stat: -rw-r--r-- 4,298 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/**
	Goal control
	Include this to all C4D_Goal objects. Functions to be overloaded:
	 * bool IsFullfilled(); - is the goal fulfilled?
	 * string GetDescription(int plr); - description of the goal
		
	@author Sven2
*/

local EditorPlacementLimit = 1; // Goals are to be placed only once (unless overloaded by the goal)

local mission_password; // mission password to be gained when the goal is fulfilled

// Initialization
func Initialize()
{
	// Do not create Library_Goal itself
	if (GetID() == Library_Goal)
	{
		Log("WARNING: Abstract Library_Goal object should not be created; object removed.");
		return RemoveObject();
	}
	// Create timer if it doesn't exist yet
	RecheckGoalTimer();
	// Done
	return _inherited(...);
}

func OnSynchronized()
{
	// Create timer if it doesn't exist yet
	RecheckGoalTimer();
	return _inherited(...);
}

func RecheckGoalTimer()
{
	// Create timer if it doesn't exist yet
	if (!GetEffect("IntGoalCheck", nil))
	{
		var timer_interval = 35;
		if (GetLeague())
			timer_interval = 2; // league has more frequent checks
		var num = AddEffect("IntGoalCheck", nil, 1, timer_interval, nil, Library_Goal);
		FxIntGoalCheckTimer(nil, num);
	}
}

protected func FxIntGoalCheckTimer(object trg, effect, int time)
{
	if (!time)
		return true;
	var curr_goal = effect.curr_goal;
	// Check current goal object
	if (curr_goal && (curr_goal->GetCategory() & C4D_Goal))
	{
		if (!curr_goal->~IsFulfilled())
		{
			curr_goal->NotifyHUD(); // The HUD has to be updated only if the goal is not fulfilled: in the other case a new goal will be chosen and that goal then updates the HUD
			return true;
		}
	}
	// Current goal is fulfilled/destroyed - check all others
	var goal_count = 0;
	for (curr_goal in FindObjects(Find_Category(C4D_Goal)))
	{
		++goal_count;
		// The first unfulfilled goal is chosen
		if (!curr_goal->~IsFulfilled())
		{
			effect.curr_goal = curr_goal;
			curr_goal->NotifyHUD();
			return true;
		}
	}
	// There were goal objects, and all goals are fulfilled
	if (goal_count)
	{
		AllGoalsFulfilled(); // Game over :(
	}
	// Kill Timer
	return FX_Execute_Kill;
}

protected func AllGoalsFulfilled()
{
	// Goals fulfilled: Set mission password(s)
	for (var goal in FindObjects(Find_Category(C4D_Goal)))
		if (goal.mission_password)
			GainMissionAccess(goal.mission_password);
	// Custom scenario goal evaluation?
	if (GameCall("OnGoalsFulfilled")) return true;
	// We're done. Play some sound and schedule game over call
	Sound("UI::Fanfare", true);
	AddEffect("IntGoalDone", nil, 1, 30, nil, Library_Goal);
}

protected func FxIntGoalDoneStop()
{
	GameOver();
}

public func NotifyHUD()
{
	// create hud objects for all players
	for (var i = 0; i < GetPlayerCount(); ++i)
	{
		NotifyPlayerHUD(GetPlayerByIndex(i));
	}
}

protected func InitializePlayer(int plr, ...)
{
	NotifyPlayerHUD(plr);
	_inherited(plr, ...);
}

private func NotifyPlayerHUD(int plr)
{
	var HUD = FindObject(Find_ID(Library_HUDController->GetGUIControllerID()), Find_Owner(plr));
	if (HUD)
		HUD->OnGoalUpdate(this);
}

// Set mission password to be gained when all goals are fulfilled
public func SetMissionAccess(string str_password)
{
	mission_password = str_password;
}

// Base implementations to be overloaded by goal objects

// Overload: return whether the goal has been fulfilled.
public func IsFulfilled() { return true; }

// Overload: return the current description for this goal.
public func GetDescription(int plr)
{
	return this.Description ?? "WARNING: GetDescription(int plr) not overloaded by goal";
}

protected func Activate(plr)
{
	if (IsFulfilled())
		return MessageWindow("$MsgGoalFulfilled$", plr);
	return MessageWindow(this->GetDescription(plr), plr);
}

// Scenario saving.
func SaveScenarioObject(props)
{
	if (!inherited(props, ...)) return false;
	if (mission_password) props->AddCall("MissionAccess", this, "SetMissionAccess", Format("%v", mission_password));
	return true;
}


/* Graphics storage */
// workaround so goals with different graphics are correctly displayed in the HUD

local goal_custom_graphics;

func SetGraphics(string new_gfx, ...)
{
	goal_custom_graphics = new_gfx;
	return inherited(new_gfx, ...);
}

func GetGraphics(int plr) { return goal_custom_graphics; }

public func IsGoal() { return true; }

local Visibility = VIS_Editor;