Commit f2d8500f06ad08de2bee95aa50302a4d263aee43
1 parent
48a504fa
fixed timeline splitting/projectile interaction crash (thanks tiger_eye :) )
Rune of the Rift paradox reduction reduced to 60 Rune of the Rift should no longer occasionally heal actors Time Skip once again removes actors from the map rather then time prisoning them git-svn-id: http://svn.net-core.org/repos/t-engine4@4820 51575b47-30f0-44d4-a5cc-537603b46e54
Showing
6 changed files
with
119 additions
and
112 deletions
... | ... | @@ -45,7 +45,7 @@ function _M:save() |
45 | 45 | end |
46 | 46 | |
47 | 47 | function _M:loaded() |
48 | - if self.project and self.project.def and self.project.def.typ and self.project.def.typ.line_function then | |
48 | + if self.project and self.project.def and self.project.def.typ and self.project.def.typ.line_function and type(self.project.def.typ.line_function.line) == "table" then | |
49 | 49 | self.project.def.typ.line_function.line = core.fov.line_import(unpack(self.project.def.typ.line_function.line)) |
50 | 50 | |
51 | 51 | -- The metatable gets lost somewhere in the save, so let's remake it | ... | ... |
... | ... | @@ -828,12 +828,22 @@ end |
828 | 828 | function _M:chronoClone(name) |
829 | 829 | local d = Dialog:simpleWaiter("Chronomancy", "Folding the space time structure...") |
830 | 830 | |
831 | - local ret = nil | |
831 | + local to_reload = {} | |
832 | + for uid, e in pairs(self.level.entities) do | |
833 | + if type(e.project) == "table" and e.project.def and e.project.def.typ and e.project.def.typ.line_function then | |
834 | + e.project.def.typ.line_function.line = { game.level.map.w, game.level.map.h, e.project.def.typ.line_function:export() } | |
835 | + to_reload[#to_reload + 1] = e | |
836 | + end | |
837 | + end | |
838 | + | |
839 | + local ret = self:cloneFull() | |
840 | + | |
841 | + for uid, e in pairs(to_reload) do e:loaded() end | |
842 | + | |
832 | 843 | if name then |
833 | 844 | self._chronoworlds = self._chronoworlds or {} |
834 | - self._chronoworlds[name] = self:cloneFull() | |
835 | - else | |
836 | - ret = self:cloneFull() | |
845 | + self._chronoworlds[name] = ret | |
846 | + ret = nil | |
837 | 847 | end |
838 | 848 | d:done() |
839 | 849 | return ret |
... | ... | @@ -852,6 +862,8 @@ function _M:chronoRestore(name, remove) |
852 | 862 | |
853 | 863 | ngame:cloneReloaded() |
854 | 864 | _G.game = ngame |
865 | + | |
866 | + game.inited = nil | |
855 | 867 | game:run() |
856 | 868 | game.key:setCurrent() |
857 | 869 | game.mouse:setCurrent() | ... | ... |
... | ... | @@ -65,7 +65,7 @@ newTalent{ |
65 | 65 | require = temporal_req1, |
66 | 66 | points = 5, |
67 | 67 | paradox = 5, |
68 | - cooldown = 1, | |
68 | + cooldown = 10, | |
69 | 69 | no_npc_use = true, |
70 | 70 | getDuration = function(self, t) return 4 + math.ceil((self:getTalentLevel(t) * 2)) end, |
71 | 71 | action = function(self, t) | ... | ... |
... | ... | @@ -66,47 +66,75 @@ newTalent{ |
66 | 66 | getDamage = function(self, t) return self:combatTalentSpellDamage(t, 25, 250) * getParadoxModifier(self, pm) end, |
67 | 67 | getDuration = function(self, t) return 2 + math.ceil(self:getTalentLevel(t) / 2 * getParadoxModifier(self, pm)) end, |
68 | 68 | action = function(self, t) |
69 | - -- Find the target and check hit | |
70 | 69 | local tg = {type="hit", range=self:getTalentRange(t), talent=t} |
71 | - local tx, ty, target = self:getTarget(tg) | |
72 | - if not tx or not ty then return nil end | |
73 | - tx, ty = checkBackfire(self, tx, ty, t.paradox) | |
74 | - local _ _, tx, ty = self:canProject(tg, tx, ty) | |
75 | - if tx then | |
76 | - target = game.level.map(tx, ty, engine.Map.ACTOR) | |
77 | - end | |
78 | - | |
79 | - -- checks for spacetime mastery hit bonus | |
80 | - local power = self:combatSpellpower() | |
81 | - if self:knowTalent(self.T_SPACETIME_MASTERY) then | |
82 | - power = self:combatSpellpower() * (1 + self:getTalentLevel(self.T_SPACETIME_MASTERY)/10) | |
83 | - end | |
70 | + local x, y, _ = self:getTarget(tg) | |
71 | + if not x or not y then return nil end | |
72 | + x, y = checkBackfire(self, x, y, t.paradox) | |
73 | + _, x, y = self:canProject(tg, x, y) | |
74 | + local target = x and game.level.map(x, y, engine.Map.ACTOR) or nil | |
75 | + if not target then return nil end | |
84 | 76 | |
85 | - if target then | |
86 | - local hit = self:checkHit(power, target:combatSpellResist() + (target:attr("continuum_destabilization") or 0)) | |
87 | - if not hit then | |
88 | - game.logSeen(target, "%s resists!", target.name:capitalize()) | |
89 | - return true | |
90 | - end | |
91 | - else | |
92 | - return | |
93 | - end | |
94 | - | |
95 | - -- deal the damage first so time prison doesn't prevent it | |
96 | - self:project(tg, tx, ty, DamageType.TEMPORAL, self:spellCrit(t.getDamage(self, t))) | |
97 | - game.level.map:particleEmitter(tx, ty, 1, "temporal_thrust") | |
77 | + local hit = self:checkHit(self:combatSpellpower(), target:combatSpellResist() + (target:attr("continuum_destabilization") or 0)) | |
78 | + if not hit then game.logSeen(target, "%s resists!", target.name:capitalize()) return true end | |
79 | + | |
80 | + target:setEffect(target.EFF_CONTINUUM_DESTABILIZATION, 100, {power=self:combatSpellpower(0.3)}) | |
81 | + self:project(tg, x, y, DamageType.TEMPORAL, self:spellCrit(t.getDamage(self, t))) | |
82 | + game.level.map:particleEmitter(x, y, 1, "temporal_thrust") | |
98 | 83 | game:playSoundNear(self, "talents/arcane") |
99 | 84 | |
100 | - -- make sure the target survives the initial hit and then time prison | |
101 | - if not target.dead then | |
102 | - if target ~= self then | |
103 | - target:setEffect(target.EFF_CONTINUUM_DESTABILIZATION, 100, {power=self:combatSpellpower(0.3)}) | |
104 | - end | |
105 | - target:setEffect(target.EFF_TIME_PRISON, t.getDuration(self, t), {}) | |
85 | + -- End it here if we've killed the target or the target is a player | |
86 | + if target.dead or target.player then return true end | |
87 | + | |
88 | + -- set up instability | |
89 | + local summoner = self | |
90 | + -- Store the current terrain | |
91 | + local terrain = game.level.map(target.x, target.y, engine.Map.TERRAIN) | |
92 | + -- Store target attributes as needed | |
93 | + local a = {} | |
94 | + a.life = target.life | |
95 | + -- Instability | |
96 | + local temporal_instability = mod.class.Object.new{ | |
97 | + old_feat = game.level.map(target.x, target.y, engine.Map.TERRAIN), | |
98 | + name = "temporal instability", type="temporal", subtype="anomaly", | |
99 | + display = '&', color=colors.LIGHT_BLUE, | |
100 | + temporary = t.getDuration(self, t), | |
101 | + canAct = false, | |
102 | + target = target, | |
103 | + act = function(self) | |
104 | + self:useEnergy() | |
105 | + self.temporary = self.temporary - 1 | |
106 | + -- return the rifted actor | |
107 | + if self.temporary <= 0 then | |
108 | + game.level.map(self.target.x, self.target.y, engine.Map.TERRAIN, self.old_feat) | |
109 | + game.level:removeEntity(self) | |
110 | + local mx, my = util.findFreeGrid(self.target.x, self.target.y, 20, true, {[engine.Map.ACTOR]=true}) | |
111 | + game.zone:addEntity(game.level, self.target, "actor", mx, my) | |
112 | + self.target.life = a.life | |
113 | + end | |
114 | + end, | |
115 | + summoner_gain_exp = true, | |
116 | + summoner = summoner, | |
117 | + } | |
118 | + | |
119 | + -- Mixin the old terrain | |
120 | + table.update(temporal_instability, terrain) | |
121 | + -- Now update the display overlay | |
122 | + local overlay = engine.Entity.new{ | |
123 | + display = '&', color=colors.LIGHT_BLUE, image="object/temporal_instability.png", | |
124 | + display_on_seen = true, | |
125 | + display_on_remember = true, | |
126 | + } | |
127 | + if not temporal_instability.add_displays then | |
128 | + temporal_instability.add_displays = {overlay} | |
106 | 129 | else |
107 | - game.logSeen(target, "%s has been killed by the temporal energy!", target.name:capitalize()) | |
130 | + table.append(temporal_instability.add_displays, overlay) | |
108 | 131 | end |
109 | - | |
132 | + | |
133 | + game.logSeen(target, "%s has moved forward in time!", target.name:capitalize()) | |
134 | + game.level:removeEntity(target) | |
135 | + game.level:addEntity(temporal_instability) | |
136 | + game.level.map(target.x, target.y, engine.Map.TERRAIN, temporal_instability) | |
137 | + | |
110 | 138 | return true |
111 | 139 | end, |
112 | 140 | info = function(self, t) | ... | ... |
... | ... | @@ -720,27 +720,32 @@ newInscription{ |
720 | 720 | getDamage = function(self, t) return 150 + self:getWil() * 4 end, |
721 | 721 | getDuration = function(self, t) return 4 end, |
722 | 722 | action = function(self, t) |
723 | - -- Find the target and check hit | |
724 | 723 | local tg = {type="hit", range=self:getTalentRange(t), talent=t} |
725 | - local tx, ty, target = self:getTarget(tg) | |
726 | - if not tx or not ty then return nil end | |
727 | - local _ _, tx, ty = self:canProject(tg, tx, ty) | |
728 | - if tx then | |
729 | - target = game.level.map(tx, ty, engine.Map.ACTOR) | |
730 | - end | |
731 | - if target and not target.player then | |
732 | - local hit = self:checkHit(self:combatSpellpower(), target:combatSpellResist() + (target:attr("continuum_destabilization") or 0)) | |
733 | - if not hit then | |
734 | - game.logSeen(target, "%s resists!", target.name:capitalize()) | |
735 | - return true | |
736 | - end | |
737 | - else | |
738 | - return | |
739 | - end | |
724 | + local x, y, _ = self:getTarget(tg) | |
725 | + if not x or not y then return nil end | |
726 | + _, x, y = self:canProject(tg, x, y) | |
727 | + local target = x and game.level.map(x, y, engine.Map.ACTOR) or nil | |
728 | + if not target then return nil end | |
729 | + | |
730 | + local hit = self:checkHit(self:combatSpellpower(), target:combatSpellResist() + (target:attr("continuum_destabilization") or 0)) | |
731 | + if not hit then game.logSeen(target, "%s resists!", target.name:capitalize()) return true end | |
732 | + | |
733 | + target:setEffect(target.EFF_CONTINUUM_DESTABILIZATION, 100, {power=self:combatSpellpower(0.3)}) | |
734 | + self:project(tg, x, y, DamageType.TEMPORAL, self:spellCrit(t.getDamage(self, t))) | |
735 | + game.level.map:particleEmitter(x, y, 1, "temporal_thrust") | |
736 | + game:playSoundNear(self, "talents/arcane") | |
740 | 737 | |
741 | - -- Create an object to time the effect and store the creature | |
742 | - -- First, clone the terrain that we are replacing | |
738 | + -- End it here if we've killed the target or the target is a player | |
739 | + if target.dead or target.player then return true end | |
740 | + | |
741 | + -- set up instability | |
742 | + local summoner = self | |
743 | + -- Store the current terrain | |
743 | 744 | local terrain = game.level.map(target.x, target.y, engine.Map.TERRAIN) |
745 | + -- Store target attributes as needed | |
746 | + local a = {} | |
747 | + a.life = target.life | |
748 | + -- Instability | |
744 | 749 | local temporal_instability = mod.class.Object.new{ |
745 | 750 | old_feat = game.level.map(target.x, target.y, engine.Map.TERRAIN), |
746 | 751 | name = "temporal instability", type="temporal", subtype="anomaly", |
... | ... | @@ -751,21 +756,23 @@ newInscription{ |
751 | 756 | act = function(self) |
752 | 757 | self:useEnergy() |
753 | 758 | self.temporary = self.temporary - 1 |
759 | + -- return the rifted actor | |
754 | 760 | if self.temporary <= 0 then |
755 | 761 | game.level.map(self.target.x, self.target.y, engine.Map.TERRAIN, self.old_feat) |
756 | 762 | game.level:removeEntity(self) |
757 | 763 | local mx, my = util.findFreeGrid(self.target.x, self.target.y, 20, true, {[engine.Map.ACTOR]=true}) |
758 | 764 | game.zone:addEntity(game.level, self.target, "actor", mx, my) |
765 | + self.target.life = a.life | |
759 | 766 | end |
760 | 767 | end, |
761 | 768 | summoner_gain_exp = true, |
762 | - summoner = self, | |
769 | + summoner = summoner, | |
763 | 770 | } |
771 | + | |
764 | 772 | -- Mixin the old terrain |
765 | 773 | table.update(temporal_instability, terrain) |
766 | 774 | -- Now update the display overlay |
767 | 775 | local overlay = engine.Entity.new{ |
768 | - -- image = "terrain/wormhole.png", | |
769 | 776 | display = '&', color=colors.LIGHT_BLUE, image="object/temporal_instability.png", |
770 | 777 | display_on_seen = true, |
771 | 778 | display_on_remember = true, |
... | ... | @@ -775,24 +782,13 @@ newInscription{ |
775 | 782 | else |
776 | 783 | table.append(temporal_instability.add_displays, overlay) |
777 | 784 | end |
785 | + | |
786 | + game.logSeen(target, "%s has moved forward in time!", target.name:capitalize()) | |
787 | + game.level:removeEntity(target) | |
788 | + game.level:addEntity(temporal_instability) | |
789 | + game.level.map(target.x, target.y, engine.Map.TERRAIN, temporal_instability) | |
778 | 790 | |
779 | - self:project(tg, tx, ty, DamageType.TEMPORAL, self:spellCrit(t.getDamage(self, t))) | |
780 | - game.level.map:particleEmitter(tx, ty, 1, "temporal_thrust") | |
781 | - game:playSoundNear(self, "talents/arcane") | |
782 | - -- Remove the target and place the temporal placeholder | |
783 | - if not target.dead then | |
784 | - if target ~= self then | |
785 | - target:setEffect(target.EFF_CONTINUUM_DESTABILIZATION, 100, {power=self:combatSpellpower(0.3)}) | |
786 | - end | |
787 | - game.logSeen(target, "%s has moved forward in time!", target.name:capitalize()) | |
788 | - game.level:removeEntity(target) | |
789 | - game.level:addEntity(temporal_instability) | |
790 | - game.level.map(target.x, target.y, engine.Map.TERRAIN, temporal_instability) | |
791 | - else | |
792 | - game.logSeen(target, "%s has been killed by the temporal energy!", target.name:capitalize()) | |
793 | - end | |
794 | - | |
795 | - self:incParadox(-120) | |
791 | + self:incParadox(-60) | |
796 | 792 | |
797 | 793 | return true |
798 | 794 | end, |
... | ... | @@ -800,7 +796,7 @@ newInscription{ |
800 | 796 | local damage = t.getDamage(self, t) |
801 | 797 | local duration = t.getDuration(self, t) |
802 | 798 | return ([[Inflicts %0.2f temporal damage. If your target survives it will be sent %d turns into the future. |
803 | - It will also lower your paradox by 120 (if you have any). | |
799 | + It will also lower your paradox by 60 (if you have any). | |
804 | 800 | Note that messing with the spacetime continuum may have unforeseen consequences.]]):format(damDesc(self, DamageType.TEMPORAL, damage), duration) |
805 | 801 | end, |
806 | 802 | short_info = function(self, t) | ... | ... |
... | ... | @@ -9,24 +9,9 @@ mod="$1" |
9 | 9 | version="$2" |
10 | 10 | exclude_ogg="$3" |
11 | 11 | |
12 | -pushd "$mod" | |
13 | -teams=`lua <<EOS | |
14 | -local init = loadfile("init.lua") | |
15 | -local d = {} | |
16 | -setfenv(init, d) | |
17 | -init() | |
18 | -if not d.teams then return end | |
19 | -for i, def in ipairs(d.teams) do | |
20 | - io.write(def[1]..":"..table.concat(def[3],":"):gsub("^/", ""):gsub(":/", ":")) | |
21 | - if i < #d.teams then io.write(";") end | |
22 | -end | |
23 | -EOS` | |
24 | -teams=`echo "$teams"| sed "s/#name#/$mod/g" | sed "s/#version#/$version/g"` | |
25 | -popd | |
26 | - | |
27 | 12 | cp -a "$mod" tmp |
28 | 13 | find tmp -name .svn -or -name '*~' | xargs rm -rf |
29 | -pushd tmp | |
14 | +cd tmp | |
30 | 15 | |
31 | 16 | if test "$exclude_ogg" -eq 1; then |
32 | 17 | IFS=$'\n'; for i in `find -name '*.ogg'`; do |
... | ... | @@ -39,25 +24,11 @@ mkdir mod |
39 | 24 | mv * mod |
40 | 25 | mv mod/data . |
41 | 26 | |
42 | -IFS=';' | |
43 | -for teamdef in `echo "$teams"`; do | |
44 | - tname=`echo "$teamdef"|cut -d: -f1` | |
45 | - tlist=`echo "$teamdef"|cut -d: -f2-` | |
46 | - echo "=== Teamdef: $tname" | |
47 | - IFS=':' | |
48 | - for list in `echo "$tlist"`; do | |
49 | - echo "=== Adding: $tlist" | |
50 | - zip --quiet -r -0 ../"$tname" "$list" | |
51 | - rm -rf "$list" | |
52 | - done | |
53 | - IFS=';' | |
54 | -done | |
55 | - | |
56 | 27 | if test "$exclude_ogg" -eq 1; then |
57 | - zip --quiet -r -0 ../"$mod"-"$version-nomusic".team * | |
28 | + zip -r -0 ../"$mod"-"$version-nomusic".team * | |
58 | 29 | else |
59 | - zip --quiet -r -0 ../"$mod"-"$version".team * | |
30 | + zip -r -0 ../"$mod"-"$version".team * | |
60 | 31 | fi |
61 | 32 | |
62 | -popd | |
33 | +cd - | |
63 | 34 | rm -rf tmp | ... | ... |
-
Please register or login to post a comment